typeRoots 오해 --TypeScript에서 npm에서 설치한 패키지에 형식 정의 파일(*.d.ts)이 없을 때의 올바른 처리 방법
12231 단어 TypeScripttsconfig
요약
npm에 설치된 패키지에 유형 정의 파일*.d.ts
이 존재하지 않는 상황에서 자신의 유형 정의 파일을 만들고 다음 1, 2의 설정을 통해 import에서 유형 정의 내용을 적용할 수 있습니다.
baseUrl
및 paths
의 조합을 통해 유형 정의 파일의 경로declare module "xxx" { ... }
외부 모듈의 환경 선언typeRoots
도 이 점을 실현할 수 있지만, typeRoots
import에서 무효이기 때문에 실제로는 상기 목적에 사용할 수 없습니다.(import는
typeRoots
에서 지정한 디렉터리에서 형식 정의 파일을 찾지 않습니다.)해설
TypeScript로 프로그램을 쓸 때 npm에 패키지가 설치되어 있으면 패키지의 형식 정의 파일 *.d.ts
을 제공하지 않을 수 있습니다 @types/xxx
패키지도 없습니다.
이 경우 strict
옵션 (또는 noImplicitAny
옵션) 을 사용하는 환경에서 구축 오류는 import 패키지를 시도할 때 형식 정의 파일을 찾을 수 없기 때문입니다.
또한 상기 이외의 환경에서는 구축 오류가 발생하지 않지만 import의 대상과 함수가 any
형이 되기 때문에 존재하지 않는 함수와 상수를 호출해도 오류가 발생하지 않으며 TypeScript의 유형 검사의 장점을 충분히 활용하지 못한다.import * as mod1 from "mod1";
// mod1パッケージをnpmからインストールしていたとしても、型定義ファイルが存在しなければ、strict環境ではビルドエラーとなる
//
// エラーの内容は下記:
// モジュール 'mod1' の宣言ファイルが見つかりませんでした。'/home/.../node_modules/mod1/index.js' は暗黙的に 'any' 型になります。
// Try `npm install @types/mod1` if it exists or add a new declaration (.d.ts) file containing `declare module 'mod1';`ts(7016)
이런 상황에서 단독제작mod1
모듈의 유형정의파일mod1.d.ts
으로import시 이 유형정의의 내용을 반영하는 방법은 크게 3가지가 있다.
import * as mod1 from "mod1";
// mod1パッケージをnpmからインストールしていたとしても、型定義ファイルが存在しなければ、strict環境ではビルドエラーとなる
//
// エラーの内容は下記:
// モジュール 'mod1' の宣言ファイルが見つかりませんでした。'/home/.../node_modules/mod1/index.js' は暗黙的に 'any' 型になります。
// Try `npm install @types/mod1` if it exists or add a new declaration (.d.ts) file containing `declare module 'mod1';`ts(7016)
TypeScript 옵션
typeRoots
에서 배치 유형 정의 파일의 디렉토리 지정tsconfig.json
{
"compilerOptions": {
"typeRoots": ["node_modules/@types", "src/@types"], // src/@types ディレクトリの中にある型定義を読み込ませたい
...
}
}
유형 스크립트 옵션 지정
baseUrl
, paths
유형 정의 파일에 조합된 경로tsconfig.json
{
"compilerOptions": {
"baseUrl": "src/typings" , // src/typings ディレクトリを起点とする (pathsの指定時は必須)
"paths": {
"mod1": ["mod1.d.ts"] // "mod1" のimport時に src/typings/mod1.d.ts を読み込ませる
// ※拡張子は省略可能のため、"mod1" や "mod1.d" も可
// ※このパス指定は省略可能で、省略した場合は自動的に src/typings/mod1.d.ts や src/typings/mod1/index.d.ts などを検索する
},
...
}
}
참고: TypeScript2.0의 Module Resolution Enhancements 정보@Quramy님의 보도임의의 유형 정의 파일에서 외부 모듈
mod1
에 대한 환경 광 선언mytypes/mod1.d.ts
declare module "mod1" { // 外部モジュール「mod1」として宣言
export function func1(): void;
export function func2(): void;
}
※ 이 모든 유형 정의 파일은 tsconfig.json
과 같은 층 이하이면 어느 곳에나 배치할 수 있습니다.typeRoots
에 배치 유형 정의 파일의 디렉터리를 지정'하는 방법은 실제로import에 반영된 방법이 정확하지 않다.typeRoots
에서 형식 정의 파일의 경로를 지정하면 실제import의 결과는 구축 오류 또는 any
입니다.※ 상기 절차와 오류 확인에 대해서는 다음 설명검증 프로세스을 참조하십시오.
과연 type Roots가 무엇인지.
typeRoots
는 삼중 사선 명령을 참조하는 경우에만 효과가 발생합니다.예를 들어, 참조
mod1
의 경우 다음 모듈 typeRoots
mod1
에 정의 파일을 포함할 수 있습니다 (import에 반영되지 않고 구축 대상에 포함될 뿐)./// <reference types="mod1" />
그러나 이 지정은 거의 baseUrl
과paths
의 조합으로 대체할 수 있고 이쪽의 조합이라면 import 때도 형식 정의 파일의 내용을 반영할 수 있기 때문에 더욱 광범위한 상황에 대응할 수 있다.따라서
baseUrl
과paths
가 설치된 지 3년이 지난 지금 상술/// <reference types="mod1" />
과typeRoots
모두 사용할 필요가 없다고 생각합니다./// <reference ... />
은(는) tslint에서 수정 객체로 감지됨참조: typeRoots is not resolved as part of compilation #27026(TypeScript 공식 저장소의 Issue)
왜 실제로 효과가 없는 typeRoots를 사용해서 전파됩니까?
정확한 원인은 알 수 없지만 아마도 다음과 같은 이유 때문일 것이다.
strict
(또는 noImplicitAny
옵션이 잘못되면 유형 정의 파일의 내용을 반영하지 않아도 any
이 되지만 구축 오류가 되지 않습니다.따라서 실제 시도에서 형식 정의 파일의 내용이 반영되지 않은 것을 알아차리기 어렵다typeRoots
의 지정과 declare module "xxx" { ... }
의 모듈에 대한 환경 선언을 조합하면 typeRoots
덕분에 형식 정의 파일을 읽은 것처럼 보일 수 있습니다 typeRoots
옵션을 사용해 왔습니다.새 코드를 쓸 때 strict
옵션을 사용하지 않았다면 지금도 눈치채지 못했을 것이다.검증 프로세스
node.js와 yarn이 설치된 환경에서 다음 절차를 수행하면import에 반영되지 않을 수 있습니다typeRoots
.
새 디렉터리에서 다음 명령을 실행하여 유형 스크립트 환경을 만듭니다.
% yarn add typescript
% yarn tsc --init # 推奨設定でtsconfig.jsonを初期化 (strictオプションも有効になる)
pokemon-names-and-types 패키지 설치(이 패키지에는 유형 정의 파일이 없음)
% yarn add pokemon-names-and-types
다음과 같은 파일 만들기
main.ts
main.tsimport { pkmn } from 'pokemon-names-and-types'
console.log("Go! %s!", pkmn.random());
같은 디렉터리에 새
types
디렉터리와 types/pokemon-names-and-types
디렉터리를 만들고 그 아래에 index.d.ts
디렉터리를 만듭니다package.json
존재하지 않는 경우 유형 스크립트 위치 확인 규칙 표준으로 읽어들여야 함index.d.ts
types/pokemon-names-and-types/index.d.tsinterface PokemonObj {
random: () => string;
}
export var pkmn: PokemonObj;
설정
tsconfig.json
의typeRoots
옵션tsconfig.json
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": ["./node_modules/@types", "./types"], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
구축 실행 - 유형 정의 파일을 찾을 수 없어 구축 오류가 발생했습니다.
% yarn tsc
$ /home/user1/dir1/node_modules/.bin/tsc
main.ts:1:22 - error TS7016: Could not find a declaration file for module 'pokemon-names-and-types'.
'/home/user1/dir1/node_modules/pokemon-names-and-types/dist/main.js' implicitly has an 'any' type.
Try `npm install @types/pokemon-names-and-types` if it exists or add a new declaration (.d.ts) file containing `declare module 'pokemon-names-and-types';`
1 import { pkmn } from 'pokemon-names-and-types'
~~~~~~~~~~~~~~~~~~~~~~~~~
Found 1 error.
끝내다
"pokemon-names-and-types
import에서 작용하지 않는다"는 보도를 전달하기 위해서였지만 생각보다 길었다
이 글을 읽고 TypeScript가 유형 정의 파일의 검색 구조와 typeRoots
, typeRoots
, baseUrl
의 역할에 대한 이해를 조금 깊게 하기를 바랍니다.(이 일대의 구조를 잘 몰라서 힘들어요...)
의견, 소감, 잘못된 지적, 혹은'기사의 이곳이 이해하기 어려우니 수정해 달라'는 요구가 있다면 본 기사의 논평과 Twitter 에서 메시지를 보내주시면 기쁩니다.
또한,'import시 어떤 순서로 형식 정의 파일을 검색하는지 알고 싶은 사람은 아래 링크에 상세한 설명이 있으니 여기를 참조하십시오.나는 이 글을 쓸 때도 아래 페이지의 내용을 참고했다.
TypeScript Handbook 읽기(16.Module Resolution)(공식 핸드북의 @murank의 일본어 번역)
Type Script Deep Dive 일본어-Fe Module 상세 정보(Yohamata를 포함한 자원봉사자의 TypeScript Deep Dive의 일본어 번역)
Reference
이 문제에 관하여(typeRoots 오해 --TypeScript에서 npm에서 설치한 패키지에 형식 정의 파일(*.d.ts)이 없을 때의 올바른 처리 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tetradice/items/b89a5dd41fcebf96379e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)