다른 곳에 게시 된 제안을 시도한 후 , 유형이 지정되지 않은 NPM 모듈을 사용하는 typescript 프로젝트를 실행할 수 없다는 것을 알게되었습니다. 아래는 최소한의 예와 내가 시도한 단계입니다.
이 최소한의 예에서는 lodash
기존 유형 정의가없는 척합니다 . 따라서 우리는 패키지를 무시 @types/lodash
하고 타이핑 파일 lodash.d.ts
을 프로젝트 에 수동으로 추가하려고합니다 .
폴더 구조
- node_modules
- Lodash
- src
- foo.ts
- 타이핑
- 커스텀
- lodash.d.ts
- 글로벌
- index.d.ts
- 커스텀
- package.json
- tsconfig.json
- typings.json
다음으로 파일.
파일 foo.ts
///<reference path="../typings/custom/lodash.d.ts" />
import * as lodash from 'lodash';
console.log('Weeee');
파일 lodash.d.ts
은 원본 @types/lodash
패키지 에서 직접 복사됩니다 .
파일 index.d.ts
/// <reference path="custom/lodash.d.ts" />
/// <reference path="globals/lodash/index.d.ts" />
파일 package.json
{
"name": "ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"typings": "./typings/index.d.ts",
"dependencies": {
"lodash": "^4.16.4"
},
"author": "",
"license": "ISC"
}
파일 tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"jsx": "react",
"module": "commonjs",
"sourceMap": true,
"noImplicitAny": true,
"experimentalDecorators": true,
"typeRoots" : ["./typings"],
"types": ["lodash"]
},
"include": [
"typings/**/*",
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
파일 typings.json
{
"name": "TestName",
"version": false,
"globalDependencies": {
"lodash": "file:typings/custom/lodash.d.ts"
}
}
보시다시피 타이핑을 가져 오는 여러 가지 방법을 시도했습니다.
- 직접 가져 오기
foo.ts
- (A)에 의해
typings
속성package.json
- 사용
typeRoots
하여tsconfig.json
파일로typings/index.d.ts
- 명시 적으로 사용하여
types
의를tsconfig.json
types
디렉토리 를 포함하여tsconfig.json
- 사용자 정의
typings.json
파일을 만들고 실행하여typings install
그러나 Typescript를 실행할 때 :
E:\temp\ts>tsc
error TS2688: Cannot find type definition file for 'lodash'.
내가 뭘 잘못하고 있죠?
답변
불행히도 이러한 사항은 현재 잘 문서화되어 있지 않지만 작동 할 수 있다고하더라도 구성을 검토하여 각 부분이 수행하는 작업과 typescript가 입력을 처리하고로드하는 방법과 관련되는 방식을 이해하도록하겠습니다.
먼저 수신 한 오류를 살펴 보겠습니다.
error TS2688: Cannot find type definition file for 'lodash'.
이 오류는 실제로 가져 오기 또는 참조 또는 ts 파일의 어디에서나 lodash를 사용하려는 시도에서 발생하지 않습니다. 오히려 typeRoots
및 types
속성 을 사용하는 방법에 대한 오해에서 비롯된 것이므로 이에 대해 좀 더 자세히 살펴 보겠습니다.
에 대한 건 typeRoots:[]
과 types:[]
속성들이 있다는 것입니다 NOT 임의의 선언 (로드 범용 방법 *.d.ts
) 파일을.
이 두 속성은 NPM 패키지 에서 타이핑 선언을 패키징하고로드 할 수있는 새로운 TS 2.0 기능과 직접 관련이 있습니다. .
이는 NPM 형식의 폴더 (예 : package.json 또는 index.d.ts 포함 된 폴더)에서만 작동한다는 점을 이해하는 것이 매우 중요합니다 .
기본값 typeRoots
은 다음과 같습니다.
{
"typeRoots" : ["node_modules/@types"]
}
기본적으로 이것은 typescript가 node_modules/@types
폴더 로 이동하여 찾은 모든 하위 폴더를 npm 패키지 로로드하려고 시도 함을 의미 합니다 .
폴더에 npm 패키지와 같은 구조가 없으면 이것이 실패한다는 것을 이해하는 것이 중요합니다.
이것은 귀하의 경우에 일어나는 일이며 초기 오류의 원인입니다.
typeRoot를 다음으로 전환했습니다.
{
"typeRoots" : ["./typings"]
}
즉, typescript는 이제 ./typings
폴더에서 하위 폴더를 검색합니다. 찾은 각 하위 폴더를 npm 모듈로로드하려고합니다.
따라서 방금 typeRoots
가리 키도록 설정 ./typings
했지만 아직 types:[]
속성 설정 이없는 것으로 가정 해 봅시다 . 다음과 같은 오류가 표시 될 수 있습니다.
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
이것은 폴더를 tsc
스캔 ./typings
하고 하위 폴더 custom
와 global
. 그런 다음이를 npm 패키지 유형 입력으로 해석하려고 시도하지만 이 폴더에 index.d.ts
또는 이 없으므로 package.json
오류가 발생합니다.
이제 types: ['lodash']
설정 하려는 속성 에 대해 조금 이야기 해 봅시다 . 이것은 무엇을합니까? 기본적으로 typescript는 내에서 찾은 모든 하위 폴더를 로드 합니다 typeRoots
. types:
속성 을 지정하면 특정 하위 폴더 만로드됩니다.
귀하의 경우에는 ./typings/lodash
폴더 를로드하라고 말하고 있지만 존재하지 않습니다. 이것이 당신이 얻는 이유입니다 :
error TS2688: Cannot find type definition file for 'lodash'
그래서 우리가 배운 것을 요약합시다. 소개 2.0 타이프 라이터 typeRoots
와 types
패키지로 로딩 선언 파일 NPM 패키지 . d.ts
npm 패키지 규칙을 따르는 폴더에 포함되지 않은 사용자 지정 입력 또는 단일 느슨한 파일이있는 경우이 두 가지 새 속성은 사용하려는 것이 아닙니다. Typescript 2.0은 이것이 소비되는 방식을 실제로 변경하지 않습니다. 여러 표준 방법 중 하나로 컴파일 컨텍스트에 이러한 파일을 포함하기 만하면됩니다.
-
.ts
파일 에 직접 포함 :
///<reference path="../typings/custom/lodash.d.ts" />
-
./typings/custom/lodash.d.ts
귀하의files: []
재산에 포함 됩니다 . -
포함
./typings/index.d.ts
당신의files: []
다음 재귀 적으로 다른 typings를 포함하는 재산 (. -
추가
./typings/**
로includes:
바라건대,이 토론을 기반으로하여 tsconfig.json
만든 변경 사항이 다시 작동 하는 이유를 알 수있을 것입니다.
편집하다:
내가 언급하는 것을 잊은 한 가지는 typeRoots
and types
property는 전역 선언 의 자동 로딩 에만 유용하다는 것입니다 .
예를 들어
npm install @types/jquery
그리고 당신이 JQuery와 유형 패키지가 자동으로로드됩니다 그런 다음, 기본 tsconfig을 사용하고 $
더 이상을 할 필요 wihtout 모든 스크립트를 통해 사용할 수 있습니다 ///<reference/>
또는import
이 typeRoots:[]
속성은 유형 패키지 가 자동으로로드 되는 위치에서 추가 위치를 추가하기위한 것입니다.
types:[]
재산의 주요 사용 사례는 (빈 배열로 설정하여) 자동로드 동작을 비활성화하는 것입니다, 다음 만이 전 세계적으로 포함 할 특정 유형을 나열.
다양한 유형의 패키지를로드하는 다른 방법 typeRoots
은 new ///<reference types="jquery" />
지시문 을 사용하는 것 입니다. 알아 차리는 types
대신 path
. 다시 말하지만 이것은 전역 선언 파일, 일반적으로 import/export
.
자, 여기에 typeRoots
. 나는 그것이 typeRoots
모듈의 글로벌 포함에 관한 것이라고 말했습니다 . 그러나 설정에 @types/folder
관계없이 표준 모듈 해상도에도 포함됩니다 typeRoots
.
특히, 명시 적으로 가져 오기 모듈은 항상 모든 우회 includes
, excludes
, files
, typeRoots
및 types
옵션. 그래서 당신이 할 때 :
import {MyType} from 'my-module';
위에서 언급 한 모든 속성은 완전히 무시됩니다. 시 관련 특성 모듈의 해상도가 있습니다 baseUrl
, paths
그리고 moduleResolution
.
사용하는 경우 기본적으로, node
모듈의 해상도를,이 파일 이름에 대한 검색을 시작합니다 my-module.ts
, my-module.tsx
, my-module.d.ts
폴더에서 시작하면 가리키는 baseUrl
구성.
이 파일을 찾지 못하면, 그것은라는 폴더를 찾습니다 my-module
다음 검색 package.json
로모그래퍼 typings
가있는 경우, 재산 package.json
또는 더 typings
그것을 말하는 내부 속성이있는 파일은 다음 검색합니다로드하지 않으려면 index.ts/tsx/d.ts
해당 폴더 내에서.
그래도 성공하지 못하면 .NET node_modules
Framework에서 시작 하는 폴더 에서 이와 동일한 항목을 검색 합니다 baseUrl/node_modules
.
또한 이러한 항목을 찾지 못하면 baseUrl/node_modules/@types
동일한 항목을 모두 검색 합니다.
아직 아무것도 발견하지 않은 경우는 상위 디렉토리로 이동 시작하고 검색합니다 node_modules
하고 node_modules/@types
있다. 파일 시스템의 루트에 도달 할 때까지 디렉토리를 계속 올라갑니다 (프로젝트 외부에 노드 모듈을 가져 오는 경우도 포함).
제가 강조하고 싶은 것은 모듈 해상도가 설정 한 것을 완전히 무시한다는 typeRoots
것입니다. 따라서 구성한 경우 typeRoots: ["./my-types"]
명시 적 모듈 확인 중에 검색되지 않습니다. 더 이상 가져 오거나 참조 할 필요없이 전체 응용 프로그램에서 사용할 수 있도록하려는 전역 정의 파일을 저장할 수있는 폴더 역할 만합니다.
마지막으로 경로 매핑 (즉, paths
속성)으로 모듈 동작을 재정의 할 수 있습니다 . 예를 들어, typeRoots
모듈을 해결하려고 할 때 사용자 정의 를 참조하지 않는다고 언급했습니다 . 그러나 마음에 들면 다음과 같이이 동작을 수행 할 수 있습니다.
"paths" :{
"*": ["my-custom-types/*", "*"]
}
이 작업은 왼쪽과 일치하는 모든 가져 오기에 대해 가져 오기를 포함하기 전에 오른쪽에서와 같이 가져 오기를 수정 해보십시오 ( *
오른쪽에있는 것은 초기 가져 오기 문자열을 나타냅니다. 예를 들어 가져 오는 경우 :
import {MyType} from 'my-types';
먼저 다음과 같이 작성한 것처럼 가져 오기를 시도합니다.
import {MyType} from 'my-custom-types/my-types'
그런 다음 찾지 못하면 접두사없이 다시 시도합니다 (배열의 두 번째 항목 *
은 초기 가져 오기를 의미합니다.
따라서 이러한 방법으로 추가 폴더를 추가하여 사용자 정의 선언 파일 또는 .ts
원하는 사용자 정의 모듈 을 검색 할 수 import
있습니다.
특정 모듈에 대한 사용자 지정 매핑을 만들 수도 있습니다.
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
이것은 당신이 할 수 있도록
import {MyType} from 'my-types';
그러나 다음에서 해당 유형을 읽으십시오. some/custom/folder/location/my-awesome-types-file.d.ts
답변
편집 : 오래되었습니다. 위의 답변을 읽으십시오.
나는 아직도 이것을 이해하지 못하지만 해결책을 찾았습니다. 다음을 사용하십시오 tsconfig.json
.
{
"compilerOptions": {
"target": "ES6",
"jsx": "react",
"module": "commonjs",
"sourceMap": true,
"noImplicitAny": true,
"experimentalDecorators": true,
"baseUrl": ".",
"paths": {
"*": [
"./typings/*"
]
}
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
를 제외한 typings.json
폴더 아래의 모든 항목을 제거 합니다 . 또한 모든 참조를 제거하십시오.typings
lodash.d.ts
///...
답변
"*": ["./types/*"]
tsconfig 경로의이 줄은 2 시간의 어려움 후에 모든 것을 수정했습니다.
{
"compilerOptions": {
"moduleResolution": "node",
"strict": true,
"baseUrl": ".",
"paths": {
"*": ["./types/*"]
},
"jsx": "react",
"types": ["node", "jest"]
},
"include": [
"client/**/*",
"packages/**/*"
],
"exclude": [
"node_modules/**/*"
]
}
유형 의 수준에 node_module 즉, 옆에 앉아 폴더 이름입니다 클라이언트 폴더 (또는 의 src 폴더)
types/third-party-lib/index.d.ts
index.d.ts가 있다declare module 'third-party-lib';
참고 : 위의 구성은 불완전한 구성으로 유형, 경로, 포함 및 제외가 어떻게 생겼는지 알 수 있습니다.
답변
나는 이것이 오래된 질문이라는 것을 알고 있지만 typescript 도구는 지속적으로 변화하고 있습니다. 이 시점에서 가장 좋은 옵션은 tsconfig.json의 “include”경로 설정에 의존하는 것입니다.
"include": [
"src/**/*"
],
기본적으로 특별히 변경하지 않는 한 모든 * .ts 및 모든 * .d.ts 파일 src/
이 자동으로 포함됩니다. 사용자 지정 typeRoots
및 사용자 지정없이 사용자 지정 형식 선언 파일을 포함하는 가장 쉽고 / 가장 좋은 방법이라고 생각합니다.types
.
참고:
답변
위에서 찾은 자세한 설명을 확장하기 위해 최근 관찰 한 내용 중 일부를 공유하고 싶습니다 . 먼저 VS Code는 작업 방식에 대해 종종 다른 의견을 가지고 있다는 점에 유의해야합니다.
최근에 작업 한 예를 보겠습니다.
src / app / components / plot-plotly / plot-plotly.component.ts :
/// <reference types="plotly.js" />
import * as Plotly from 'plotly.js';
VS Code는 다음과 같이 불평 할 수 있습니다. No need to reference "plotly.js", since it is imported. (no-reference import) tslint(1)
프로젝트를 시작하면 오류없이 컴파일되지만 해당 줄을 제거하면 시작 중에 다음 오류가 나타납니다.
ERROR in src/app/components/plot-plotly/plot-plotly.component.ts:19:21 - error TS2503: Cannot find namespace 'plotly'.
reference types
import 문 뒤에 지시문을 배치하는 경우에도 동일한 오류 메시지가 나타납니다 .
중요 : /// <reference types="plotly.js" />
은 유형 스크립트 파일의 앞에 있어야합니다! 관련 문서 참조 : 링크
삼중 슬래시 지시문은 포함하는 파일의 맨 위에서 만 유효합니다.
또한 tsconfig.json 및 typeRoot 섹션에 대한 문서를 읽는 것이 좋습니다. 링크
유형 패키지는 index.d.ts라는 파일이있는 폴더 또는 유형 필드가있는 package.json이있는 폴더입니다.
위의 참조 지시문은 다음 시나리오에서 작동합니다.
types / plotly.js / index.d.ts : ( 링크 )
declare namespace plotly {
export interface ...
}
과
tsconfig.json :
"compilerOptions": {
...
"typeRoots": [
"types/",
"node_modules/@types"
],
...
참고 : 위 설정에서 두 개의 “plotly.js”는 두 개의 다른 폴더 및 파일 (라이브러리 / 정의)을 의미합니다. 가져 오기는 “node_modules / plotly.js”폴더에 적용됩니다 (npm install plotly.js
)에 적용되고 참조는 types / plotly.js에 적용됩니다.
내 프로젝트에서 VS Code 불평과 “two”plotly.js의 모호함을 해결하기 위해 다음 구성으로 끝났습니다.
- 모든 파일이 원래 위치에 남아 있음
- tsconfig.json :
"compilerOptions": {
...
"typeRoots": [
"./",
"node_modules/@types"
],
...
- src / app / components / plot-plotly / plot-plotly.component.ts :
/// <reference types="types/plotly.js" />
import * as Plotly from 'plotly.js';
plotDemo() {
// types using plotly namespace
const chunk: plotly.traces.Scatter = {
x: [1, 2, 3, 4, 5],
y: [1, 3, 2, 3, 1],
mode: 'lines+markers',
name: 'linear',
line: { shape: 'linear' },
type: 'scatter'
};
// module call using Plotly module import
Plotly.newPlot(...);
}
내 시스템의 DevDeps :
- “ts-node”: “~ 8.3.0”,
- “tslint”: “~ 5.18.0”,
- “typescript”: “~ 3.7.5”