고품질 TypeScript 유형 정의를 위한 저장소입니다.
이 README는 Español, English, Русский, 简体中文, Português, Italiano, 日本語 및 Français에서도 읽을 수 있습니다!
관리자 매뉴얼 바로가기
확실히 Typed는 최근 적절한 pnpm
모노레포로 변경되었습니다. 이 저장소의 패키지 레이아웃 변경 사항에 대해 이 문서를 다시 읽어 볼 수 있습니다.
최소한 git clean -fdx
repo(또는 Windows의 경우 node ./scripts/clean-node-modules.js
)를 실행하여 node_modules
정리하고 pnpm install --filter .
작업공간 루트를 설치합니다. pnpm install
에 대한 자세한 내용은 추가 섹션을 참조하세요.
이 섹션에서는 저장소 및 게시 프로세스의 상태를 추적합니다. PR 및 패키지에 문제가 있는 기여자에게 도움이 될 수 있습니다.
여기에 잘못된 내용이 있거나 위의 내용 중 하나라도 실패하는 경우 TypeScript Community Discord 서버의 명확히 입력된 채널을 통해 알려주시기 바랍니다.
TypeScript 핸드북을 참조하세요.
이것이 선호되는 방법입니다. 예를 들어:
npm install --save-dev @types/node
범위가 지정된 모듈에 대한 입력을 설치하려면 @
를 제거하고 범위 뒤에 이중 밑줄을 추가하세요. 예를 들어 @babel/preset-env
에 대한 입력을 설치하려면 다음을 수행합니다.
npm install --save-dev @types/babel__preset-env
그러면 해당 유형이 컴파일러에 의해 자동으로 포함됩니다. 모듈을 사용하지 않는 경우 types
참조를 추가해야 할 수도 있습니다.
/// <reference types="node" />
핸드북에서 자세한 내용을 확인하세요.
npm 패키지 "foo"의 경우 "@types/foo"에 입력됩니다.
패키지에 package.json
의 types
또는 typings
키를 사용하여 지정된 타이핑이 있는 경우 npm 레지스트리는 패키지에 다음과 같이 사용 가능한 바인딩이 있음을 표시합니다.
평소와 같이 전체 저장소를 복제할 수 있지만 크기가 크고 대규모 패키지 유형 디렉터리가 포함되어 있습니다. 복제하는 데 시간이 좀 걸리고 불필요하게 다루기 어려울 수 있습니다.
자신과 관련된 유형 패키지 만 포함하는 보다 관리하기 쉬운 복제본을 위해 git의 sparse-checkout
및 --filter
기능을 사용할 수 있습니다. 이렇게 하면 복제 시간이 줄어들고 Git 성능이 향상됩니다.
️ 이를 위해서는 최소 git 버전 2.27.0이 필요하며 이는 대부분의 시스템에서 기본값보다 최신일 수 있습니다. 이전 버전에서는 더 복잡한 절차를 사용할 수 있지만 이 가이드에서는 다루지 않습니다.
git clone --sparse --filter=blob:none <forkedUrl>
--sparse
sparse-checkout 파일을 초기화하므로 작업 디렉터리는 저장소 루트에 있는 파일로만 시작됩니다.--filter=blob:none
모든 커밋 기록을 포함하지만 파일은 제외하여 필요한 경우에만 가져옵니다.git sparse-checkout add types/<type> types/<dependency-type> ...
pnpm test <package to test>
실행합니다. 기존 패키지를 편집하기 위해 PR을 만들 때 dt-bot
패키지 소유자를 @-멘션해야 합니다. 그렇지 않은 경우 PR과 관련된 댓글에서 직접 그렇게 할 수 있습니다.
귀하가 라이브러리 작성자이고 귀하의 패키지가 TypeScript로 작성된 경우, 확실히 형식화된 형식으로 게시하는 대신 생성된 선언 파일을 패키지에 번들로 묶습니다. 유형 주석에 JSDoc을 사용하여 JavaScript 파일에서 선언 파일을 생성할 수도 있습니다.
npm 패키지에 대한 입력을 추가하는 경우 동일한 이름의 디렉터리를 만듭니다. 입력을 추가하려는 패키지가 npm에 없는 경우 선택한 이름이 npm의 패키지 이름과 충돌하지 않는지 확인하세요. ( npm info <my-package>
사용하여 <my-package>
패키지가 있는지 확인할 수 있습니다.)
패키지의 구조는 다음과 같아야 합니다.
파일 | 목적 |
---|---|
index.d.ts | 여기에는 패키지에 대한 입력이 포함됩니다. |
<my-package>-tests.ts | 여기에는 입력을 테스트하는 샘플 코드가 포함되어 있습니다. 이 코드는 실행되지 않지만 유형이 확인됩니다. |
tsconfig.json | 이를 통해 패키지 내에서 tsc 실행할 수 있습니다. |
.eslintrc.json | (드물게) eslint용으로 작성된 Lint 규칙을 비활성화하는 데에만 필요합니다. |
package.json | 이름, 버전, 종속성을 포함하여 패키지에 대한 메타데이터를 포함합니다. |
.npmignore | 패키지에 포함할 파일을 지정합니다. |
npx dts-gen --dt --name <my-package> --template module
실행하여 이를 생성하세요. dts-gen에서 모든 옵션을 확인하세요.
index.d.ts
외에 .d.ts
파일이 있는 경우 해당 파일이 index.d.ts
또는 테스트에서 참조되는지 확인하세요.
확실히 입력된 회원은 정기적으로 새 PR을 모니터링하지만 다른 PR의 수가 많아지면 속도가 느려질 수 있다는 점을 명심하세요.
좋은 예제 패키지는 base64-js를 참조하세요.
패키지가 자체 유형을 번들로 묶는 경우 혼동을 피하기 위해 유형을 명확하게 유형에서 제거해야 합니다.
pnpm run not-needed <typingsPackageName> <asOfVersion> [<libraryName>]
실행하여 이를 제거할 수 있습니다.
<typingsPackageName>
: 삭제할 디렉터리의 이름입니다.<asOfVersion>
: 이 버전의 스텁이 @types/<typingsPackageName>
에 게시됩니다. 현재 게시된 버전보다 높아야 하며 npm의 <libraryName>
버전이어야 합니다.<libraryName>
: 명확한 유형의 유형을 대체하는 npm 패키지의 이름입니다. 일반적으로 이는 <typingsPackageName>
과 동일하며 이 경우 생략할 수 있습니다. 패키지가 확실히 유형화된 적이 없는 경우에는 notNeededPackages.json
에 추가할 필요가 없습니다.
pnpm test <package to test>
실행하여 변경 사항을 테스트합니다. 여기서 <package to test>
는 패키지 이름입니다. 개별 package.json이 테스트 스크립트를 정의하지 않기 때문에 이 항목은 확실히 Typed 디렉터리에서 실행해야 합니다.
이 스크립트는 dtslint를 사용하여 dts 파일에 대해 TypeScript 컴파일러를 실행합니다.
모든 변경 사항이 준비되면 pnpm run test-all
사용하여 변경 사항이 다른 모듈에 어떤 영향을 미치는지 확인하세요.
attw
) 확인 dtslint에는 @arethetypeswrong/cli의 모듈 형식 및 package.json
구성 검사가 포함되어 있습니다. 확실히 유형이 지정된 패키지와 비교하기 위해 SemVer-major 호환 구현 패키지를 npm에서 찾을 수 있는 경우에만 검사가 실행됩니다. ( package.json
에서 nonNpm
으로 표시된 DefinitelyTyped 패키지는 건너뜁니다.)
현재 많은 패키지가 attw
검사에 실패하므로 수정이 필요합니다. 점진적인 진행을 허용하기 위해 실패한 attw
검사는 패키지가 attw.json
의 failingPackages
에 나열될 때 dtslint
실행에 실패하지 않지만 pnpm test my-package
출력에는 계속 보고됩니다. 패키지를 수정하는 경우 attw
검사에서 dtslint
실행 실패가 시작될 수 있도록 failingPackages
에서 패키지를 제거하세요.
attw
가 보고한 모든 문제에는 출력에 링크된 문서가 있습니다. 문제를 방지하는 데 도움이 되는 몇 가지 경험 법칙:
DefinedTyped 패키지의 package.json
에는 일치하는 type
있어야 하며 구현 패키지가 package.json
에서 이를 사용하는 경우 필드를 exports
. 예를 들어 구현 package.json
이 다음과 같은 경우:
{
"name" : " my-package " ,
"version" : " 1.0.1 " ,
"type" : " module " ,
"main" : " dist/cjs/index.cjs " ,
"exports" : {
"." : {
"import" : " ./dist/esm/index.js " ,
"require" : " ./dist/cjs/index.cjs "
},
"./subpath" : {
"import" : " ./dist/esm/subpath.js " ,
"require" : " ./dist/cjs/subpath.cjs "
}
}
}
확실히 유형이 지정된 package.json
은 다음과 같아야 합니다.
{
"name" : "@types/my-package" ,
"version" : "1.0.9999" ,
"type" : "module" ,
"types" : "index.d.ts" ,
"exports" : {
"." : {
"import" : "./index.d.ts" ,
"require" : "./index.d.cts"
} ,
"./subpath" : {
"import" : "./subpath.d.ts" ,
"require" : "./subpath.d.cts"
}
}
}
각 exports
하위 경로가 반영되고 각 JavaScript 파일에는 일치하는 파일 확장자를 가진 해당 선언 파일이 있습니다. .d.ts
파일은 .mjs
또는 .cjs
파일이 아닌 .js
파일 형식을 지정합니다.
구현 패키지가 module.exports = ...
사용하는 경우 명확히 유형화된 패키지는 내보내기 export default
아닌 export =
사용해야 합니다. (또는 module.exports
가 명명된 속성의 개체인 경우, DefinedTyped 패키지는 일련의 명명된 내보내기를 사용할 수 있습니다.) 이 문제를 해결하는 데 가장 일반적인 장애물은 기본 내보내기 외에 유형을 내보내는 방법에 대한 혼란입니다. 예를 들어 다음 유형이 export default
잘못 사용하고 있다고 가정합니다.
export interface Options {
// ...
}
export default function doSomething ( options : Options ) : void ;
export default
export =
로 변경하면 오류가 발생합니다.
export interface Options {
// ...
}
declare function doSomething ( options : Options ) : void ;
export = doSomething ;
// ^^^^^^^^^^^^^^^^^
// Error: An export assignment cannot be used in a module with other exported elements.
이 문제를 해결하려면 함수와 이름이 같은 네임스페이스 내부로 유형을 이동하세요.
declare namespace doSomething {
export interface Options {
// ...
}
}
declare function doSomething ( options : doSomething . Options ) : void ;
export = doSomething ;
문제를 해결하는 데 도움이 필요하면 TypeScript Community Discord 서버의 PowerfulTyped 채널에 문의하세요.
npm 패키지에 대한 입력을 추가하는 경우 동일한 이름의 디렉터리를 만듭니다. 입력을 추가하려는 패키지가 npm에 없으면 package.json
에서 "nonNpm": true
설정하고 선택한 이름이 npm의 패키지 이름과 충돌하지 않는지 확인하세요. ( npm info <my-package>
사용하여 <my-package>
패키지가 있는지 확인할 수 있습니다.)
드문 경우지만 nonNpm
"conflict"
로 설정될 수 있습니다. 이는 npm에 동일한 이름을 가진 패키지가 있지만 유형이 의도적으로 해당 패키지와 충돌함을 나타냅니다. 이는 @types/node
와 같은 환경을 정의하는 패키지 또는 aws-lambda
와 같은 더미 패키지의 경우에 해당됩니다. 가능하면 "conflict"
사용하지 마세요.
<my-package>-tests.ts
가져오는 *.ts
파일과 함께 테스트 파일로 간주되는 <my-package>-tests.ts
파일이 있어야 합니다. 모듈 폴더에 테스트 파일이 표시되지 않으면 <my-package>-tests.ts
를 생성하세요. 이러한 파일은 @types/<my-package>
로 제공되는 *.d.ts
파일에서 내보낸 API의 유효성을 검사하는 데 사용됩니다. 그들은 스스로 배송하지 않습니다.
*.d.ts
파일에 대한 변경 사항에는 사용 중인 API를 보여주는 해당 *.ts
파일 변경 사항이 포함되어야 합니다. 그래야 누군가 실수로 여러분이 의존하는 코드를 손상시키지 않습니다. 예를 들어, 함수에 새 매개변수를 추가하는 .d.ts
파일의 함수에 대한 다음 변경 사항은 다음과 같습니다.
index.d.ts
:
- export function twoslash(body: string): string
+ export function twoslash(body: string, config?: { version: string }): string
<my-package>-tests.ts
:
import {twoslash} from "./"
// $ExpectType string
const result = twoslash("//")
+ // Handle options param
+ const resultWithOptions = twoslash("//", { version: "3.7" })
+ // When the param is incorrect
+ // @ts-expect-error
+ const resultWithOptions = twoslash("//", { })
테스트 코드를 어디에서 시작해야 할지 궁금하다면 원본 패키지의 README에 있는 예제를 참조하는 것이 좋습니다.
변경된 파일을 고려하는 이 저장소의 루트에서 npm test <package to test>
사용하여 변경 사항을 확인할 수 있습니다.
표현식이 주어진 유형임을 주장하려면 $ExpectType
사용하고 컴파일 오류를 주장하려면 @ts-expect-error
사용하십시오. 예:
// $ExpectType void
f ( 1 ) ;
// @ts-expect-error
f ( "one" ) ;
자세한 내용은 dtslint 추가 정보를 참조하세요.
.eslintrc.json
어떤 이유로 린트 규칙을 비활성화해야 하는 경우 특정 줄에 대해 이를 비활성화하세요.
// eslint-disable-next-line no-const-enum
const enum Const {
One ,
}
const enum Enum { // eslint-disable-line no-const-enum
Two ,
}
.eslintrc.json을 사용하여 규칙을 비활성화할 수 있지만 새 패키지에서는 비활성화하면 안 됩니다. 전체 패키지에 대한 규칙을 비활성화하면 검토가 더 어려워집니다.
tsconfig.json
tsconfig.json
noImplicitAny
, noImplicitThis
, strictNullChecks
및 strictFunctionTypes
true
로 설정되어 있어야 합니다.
tsconfig.json
편집하여 새 테스트 파일을 추가하거나, "target": "es6"
(비동기 기능에 필요)을 추가하거나, "lib"
에 추가하거나 "jsx"
컴파일러 옵션을 추가할 수 있습니다.
esModuleInterop
/ allowSyntheticDefaultImports
핵심요약: esModuleInterop
및 allowSyntheticDefaultImports
는 tsconfig.json
에서 허용되지 않습니다 .
이러한 옵션을 사용하면 CJS 내보내기에 대한 기본 가져오기를 작성하여 Node 및 일부 JS 번들러에서 CJS와 ES 모듈 간의 내장 상호 운용성을 모델링할 수 있습니다.
// component.d.ts declare class Component { } // CJS export, modeling `module.exports = Component` in JS export = Component ; // index.d.ts // ESM default import, only allowed under 'esModuleInterop' or 'allowSyntheticDefaultExports' import Component from "./component" ;
index.d.ts
에서 가져오기의 컴파일 시간 유효성은 해당 유형의 사용자가 상속하지 않는 특정 컴파일 설정에 따라 달라지므로 확실히 유형이 지정된에서 이 패턴을 사용하면 사용자가 자신의 컴파일 설정을 변경해야 하며 이는 올바르지 않을 수 있습니다. 런타임을 위해. 대신 광범위하고 구성 독립적인 호환성을 보장하기 위해 CJS 내보내기에 대한 CJS 가져오기를 작성해야 합니다.// index.d.ts // CJS import, modeling `const Component = require("./component")` in JS import Component = require ( "./component" ) ;
package.json
이 파일은 필수이며 다음 템플릿을 따라야 합니다.
{
"private" : true ,
"name" : "@types/PACKAGE-NAME" ,
"version" : "1.2.9999" ,
"projects" : [
"https://aframe.io/"
] ,
"dependencies" : {
"@types/DEPENDENCY-1" : "*" ,
"@types/DEPENDENCY-2" : "*"
} ,
"devDependencies" : {
"@types/PACKAGE-NAME" : "workspace:."
} ,
"owners" : [
{
"name" : "Your Name Here" ,
"githubUsername" : "ghost"
}
]
}
package.json
은 다른 @types
패키지를 포함한 모든 종속성을 지정합니다.
허용된 외부 종속성 목록에 @types
아닌 종속성을 추가해야 합니다. 피카데이(Pikaday)가 좋은 예이다. 이러한 추가 사항은 관리자의 승인을 받아 @types
패키지가 악성 패키지에 의존하지 않도록 할 수 있는 기회를 제공합니다.
구현 패키지가 ESM을 사용하고 "type": "module"
지정하는 경우 다음과 일치하도록 package.json을 수정해야 합니다.
{
"type" : " module "
}
이는 구현 패키지의 package.json에 exports
있는 경우에도 적용됩니다.
확실히 입력된 항목은 package.json
에서 peerDependencies
허용합니다. 피어 종속성은 패키지 관리자가 예기치 않게 너무 새로운 버전이나 동일한 패키지의 두 개 이상의 버전을 설치하는 상황을 방지하는 데 도움이 됩니다. 그러나 피어 종속성에는 단점이 있습니다. 패키지 관리자는 피어 종속성을 처리하는 방식이 다릅니다(예: yarn
자동으로 설치하지 않으며, npm
불일치에 대해 --legacy-peer-deps
필요합니다). 따라서 새로운 피어 종속성을 도입하는 PR에는 관리자 승인이 필요하며 특정 상황으로 제한되어야 합니다.
일반적으로 유형 패키지는 업스트림 패키지가 동일한 패키지(또는 해당 유형)에 대한 피어 종속성을 갖는 경우에만 피어 종속성을 가져야 합니다. 예를 들어, React 구성 요소용 DT 패키지는 @types/react@*
에 대한 피어 종속성을 지정할 수 있습니다. 소비자가 JSX를 사용하려면 먼저 @types/react
설치해야 하기 때문입니다. 소비자가 프로젝트에 @types/react@16
설치했지만 npm에서 최신 버전의 @types/react
사용할 수 있는 경우 피어 종속성은 패키지 관리자가 최신 버전 대신 @types/react@16
선택하는 데 도움이 될 수 있습니다. 마찬가지로 chai-as-promised
chai
에 대한 피어 종속성을 가지므로 @types/chai-as-promised
@types/chai
에 대한 피어 종속성을 가져야 합니다.
업스트림 패키지가 유형 패키지에 대한 피어 종속성을 갖지 않지만 피어 종속성은 여전히 적절한 경우가 있습니다. 이는 일반적으로 업스트림 패키지가 다른 패키지를 확장하고 해당 패키지가 존재한다고 가정하는 경우이므로 다른 패키지를 확장할 때 피어 종속성을 선언 했어야 했지만 그렇지 않았습니다. 예를 들어, chai-match-pattern
chai
확장하지만 chai
에 대한 피어 종속성을 선언하지는 않지만 작동하려면 필요합니다. @types/chai-match-pattern
@types/chai
에 대한 피어 종속성을 가져야 합니다.
업스트림 패키지의 일반적인 종속성으로 인해 패키지가 API의 일부로 다른 패키지의 유형을 단순히 노출하는 경우 피어 종속성을 사용해서는 안 됩니다 . 예를 들어, express
"dependencies"
에는 qs
있습니다. 사용자가 express
설치할 때 qs
수동으로 설치할 필요가 없습니다. 마찬가지로 @types/express
의 "dependencies"
에는 @types/qs
있습니다. @types/qs
@types/express
의 피어 종속성으로 선언하는 것은 올바르지 않습니다. 왜냐하면 일부 다운스트림 소비자가 @types/qs
수동으로 설치해야 하기 때문입니다.
.npmignore
이 파일은 각 @types
패키지에 포함될 파일을 정의합니다. 특정한 형태를 취해야 합니다. 저장소에 버전이 하나만 있는 패키지의 경우:
*
! ** / * .d.ts
! ** / * .d.cts
! ** / * .d.mts
! ** / * .d. * .ts
이는 "모든 파일을 무시하지만 선언 파일은 무시하지 마십시오"를 의미합니다. 저장소에 둘 이상의 버전이 있는 패키지의 경우 "최신" 버전(최상위 수준)에는 다음과 같은 항목이 포함되어야 합니다.
*
! ** / * .d.ts
! ** / * .d.cts
! ** / * .d.mts
! ** / * .d. * .ts
/ v15 /
/ v16 /
/ v17 /
이전 .npmignore
와 동일하지만 버전이 지정된 각 하위 디렉터리를 무시합니다.
이 파일에 잘못된 내용이 포함되어 있고 의도한 값을 제공하면 CI가 실패합니다. 이 파일에 무엇이 포함되어 있든 게시자는 선언 파일만 게시합니다.
pnpm dprint fmt -- 'path/to/package/**/*.ts'
실행할 수 있습니다..vscode/settings.template.json
(또는 다른 편집기에 해당하는 항목)을 사용하는 것이 좋습니다.function sum(nums: number[]): number
: 함수가 해당 매개변수에 쓰지 않는 경우 ReadonlyArray
사용합니다.interface Foo { new(): Foo; }
: 새로 생성할 수 있는 객체 유형을 정의합니다. 아마도 declare class Foo { constructor(); }
.const Class: { new(): IClass; }
: 클래스 선언을 사용하는 것을 선호합니다 class Class { constructor(); }
새로운 가능 상수 대신.getMeAT<T>(): T
: 유형 매개변수가 어떤 매개변수 유형에도 나타나지 않으면 실제로 일반 함수가 없고 위장된 유형 어설션만 있는 것입니다. 실제 유형 주장을 사용하는 것을 선호합니다(예: getMeAT() as number
사용). 유형 매개변수가 허용되는 예: function id<T>(value: T): T;
. 허용되지 않는 예: function parseJson<T>(json: string): T;
. 예외: new Map<string, number>()
는 괜찮습니다.Function
및 Object
유형을 사용하는 것은 거의 좋은 생각이 아닙니다. 99%의 경우 더 구체적인 유형을 지정하는 것이 가능합니다. 예를 들어 함수의 경우 (x: number) => number
이고 객체의 경우 { x: number, y: number }
입니다. 유형에 대한 확실성이 전혀 없다면 Object
아닌 any
올바른 선택입니다. 유형에 대해 알려진 유일한 사실이 객체라는 것뿐이라면 Object
또는 { [key: string]: any }
가 아닌 object
유형을 사용하세요.var foo: string | any
: 공용체 유형에서 any
사용하는 경우 결과 유형은 여전히 any
입니다. 따라서 이 유형 주석의 string
부분이 유용 해 보일 수 있지만 실제로는 단순히 any
사용하는 것 이상의 추가 유형 검사를 제공하지 않습니다. 의도에 따라 허용 가능한 대안은 any
, string
또는 string | object
.핵심요약:
.github/CODEOWNERS
수정하지 마세요. 항상package.json
의 소유자 목록을 수정하세요.
DT에는 특정 모듈 유형의 품질을 유지하려는 사람들인 "정의 소유자"라는 개념이 있습니다.
자신을 정의 소유자로 추가하려면 package.json
에서 owners
배열을 수정하세요.
"owners" : [
{
"name" : " Some Person " ,
"githubUsername" : " somebody "
},
{
"name" : " Some Corp " ,
"url" : " https://example.org "
}
]
이 목록은 기여에 대한 크레딧을 제공하는 데 사용되지 않습니다 . PR 리뷰 관리에만 사용됩니다.
일주일에 한 번 정의 소유자는 정보 소스인 .github/CODEOWNERS 파일에 동기화됩니다.
Defined Typed는 GitHub에서 가장 활동적인 리포지토리 중 하나입니다. 프로젝트가 어떻게 진행되었는지 궁금했을 것입니다. @johnnyreilly는 확실히 입력된 항목의 역사를 썼습니다. @borisyankov가 만든 리포지토리부터 TypeScript 생태계의 중추적인 부분이 된 지점까지의 Defined Typed 초기 이야기를 들려줍니다. 여기에서 확실히 입력된 이야기를 읽을 수 있습니다.
@types
패키지 사이의 관계는 정확히 무엇입니까? master
브랜치는 확실히 Typed-tools 덕분에 npm의 @types
범위에 자동으로 게시됩니다.
상황에 따라 다르지만 대부분의 풀 요청은 일주일 이내에 병합됩니다. 일부 PR은 모듈 소유자가 병합할 수 있으며 훨씬 빠르게 병합될 수 있습니다. 대충:
모듈 유형만 변경하고 해당 테스트 변경 사항이 있는 PR은 훨씬 빠르게 병합됩니다.
정의의 package.json
에 나열된 소유자가 승인한 PR은 일반적으로 더 빠르게 병합됩니다. 새로운 정의에 대한 PR은 유지관리자의 추가 검토가 필요하므로 더 많은 시간이 소요됩니다. 각 PR은 병합되기 전에 TypeScript 또는 명확한 유형의 팀원이 검토하므로 인적 요인으로 인해 지연이 발생할 수 있으므로 기다려 주시기 바랍니다. 유지관리자가 공개 PR을 통해 작업하는 동안 진행 상황을 보려면 새 끌어오기 요청 상태 보드를 확인하세요.
npm에서 매주 수백만 건의 다운로드가 이루어지는 Node/Express/Jest와 같이 매우 인기 있는 모듈을 변경하려면 기여 요구 사항이 약간 더 높습니다. 이러한 프로젝트의 변경은 생태계에 막대한 영향을 미칠 수 있으므로 우리는 변경 사항을 매우 주의 깊게 다룹니다. 이러한 모듈에는 DT 유지관리자의 승인과 모듈 소유자의 열정적인 지원이 모두 필요합니다. 이를 통과하기 위한 기준은 상당히 높을 수 있으며, 챔피언이 없기 때문에 PR이 정체될 수 있습니다. 아무도 약속하지 않는다는 사실을 알게 되면 PR에 더 작은 초점을 맞추도록 노력하세요.
@types
npm 패키지는 언제 업데이트되나요?npm 패키지는 1시간 이내에 업데이트되어야 합니다. 한 시간 이상이 지난 경우 TypeScript Community Discord 서버의 확실히 입력된 채널에 PR 번호를 언급하면 현재 관리자가 올바른 팀원에게 조사를 요청할 것입니다.
<reference types="" />
사용해야 하나요, 아니면 가져오기를 사용해야 하나요? 참조하는 모듈이 모듈( export
사용)인 경우 가져오기를 사용하세요. 참조하는 모듈이 앰비언트 모듈( declare module
사용)이거나 전역을 선언하는 경우 <reference types="" />
사용하세요.
"noImplicitAny": true
, "noImplicitThis": true
또는 "strictNullChecks": true
가 누락된 tsconfig.json
있습니다.그렇다면 그들은 틀렸고 우리는 아직 눈치 채지 못했습니다. 이 문제를 해결하려면 풀 요청을 제출하여 도움을 받을 수 있습니다.
네, dprint를 사용하고 있습니다. 편집기에 dprint 확장 프로그램을 사용하는 것이 좋습니다.
또는 코드 형식을 자동으로 지정하는 git Hook을 활성화할 수 있습니다. pnpm run setup-hooks
실행하세요. 그런 다음 커밋하면 변경된 파일에 대해 dprint fmt
명령이 실행됩니다. 부분 복제를 활용하는 경우 setup-hooks
스크립트를 실행하기 전에 git sparse-checkout add .husky
호출하여 git 후크를 확인하십시오.
풀 요청을 병합하려면 올바른 형식이 필요하지 않습니다. 서식이 지정되지 않은 코드는 병합 후 자동으로 다시 서식이 지정됩니다.
VS Code 사용자인 경우
.vscode/settings.template.json
파일을.vscode/settings.json
에 복사하는 것이 좋습니다. 해당 템플릿은 dprint VS Code 확장을 저장소의 기본 포맷터로 설정합니다.
현재 요청된 정의는 다음과 같습니다.
유형이 웹 표준의 일부인 경우 기본 lib.dom.d.ts
의 일부가 될 수 있도록 TypeScript-DOM-lib-generator에 기여해야 합니다.
예를 들어 도우미 유형이나 사양에 대한 유형을 작성하는 경우와 같이 소스 JavaScript 코드가 전혀 없는 경우에는 확실히 유형이 아닌 유형을 직접 게시해야 합니다. @types 패키지는 기존 JavaScript 코드에 대한 유형을 제공하기 위한 것이므로 @types
패키지를 직접 가져올 수는 없습니다. 즉, import type { ... } from "@types/foo"
처럼 사용되는 명확한 형식의 패키지를 생성해서는 안 됩니다. 또한 foo
설치되어 있지 않을 때 import type { ... } from "foo"
쓸 것이라고 기대해서는 안 됩니다.
이는 브라우저 전용 JavaScript 라이브러리에 대한 유형이나 node, bun 등과 같은 전체 환경에 대한 유형을 제공하는 것과는 다릅니다. 여기서 유형은 암시적으로 또는 /// <references types="foo" />
사용하여 해결됩니다.
chai-http와 같은 일부 패키지는 함수를 내보냅니다.
ES6 스타일로 이 모듈을 가져오기 import * as foo from "foo";
오류가 발생합니다.
오류 TS2497: 'foo' 모듈은 모듈이 아닌 엔터티로 확인되며 이 구성을 사용하여 가져올 수 없습니다.
이 오류는 함수 선언을 동일한 이름의 빈 네임스페이스와 병합하여 억제할 수 있지만 이 방법은 권장되지 않습니다. 이것은 이 문제와 관련하여 일반적으로 인용되는 스택 오버플로 답변입니다.
import foo = require("foo");
사용하여 모듈을 가져오는 것이 더 적절합니다. 통사론. 그럼에도 불구하고 import foo from "foo";
두 가지 옵션이 있습니다:
--allowSyntheticDefaultImports
컴파일러 옵션을 사용할 수 있습니다.--esModuleInterop
컴파일러 옵션을 사용할 수 있습니다(TypeScript 2.7부터). export =
사용하지만 기본 가져오기를 사용하는 것을 선호합니다. export =
export default
로 변경할 수 있나요? 이전 질문과 마찬가지로 --allowSyntheticDefaultImports
또는 --esModuleInterop
컴파일러 옵션 사용을 참조하세요.
유형 정의가 정확하다면 변경하지 마십시오. npm 패키지의 경우 node -p 'require("foo")'
모듈을 가져오는 데 작동하면 export =
가 정확하고 node -p 'require("foo").default'
모듈을 가져오는 데 작동하면 export default
이 정확합니다. .
그런 다음 package.json
에 "minimumTypeScriptVersion": "XY"
지정하여 지원되는 최소 버전을 설정하게 됩니다.
그러나 프로젝트에서 3.7 이상과 호환되는 유형을 동시에 3.6 이하와 호환되는 유형을 유지해야 하는 경우 typesVersions
기능을 사용해야 합니다. 공식 TypeScript 문서에서 이 기능에 대한 자세한 설명을 찾을 수 있습니다.
시작하는 데 도움이 되는 간단한 예는 다음과 같습니다.
package.json
에 typesVersions
추가해야 합니다.
{
"private" : true ,
"types" : " index " ,
"typesVersions" : {
"<=3.6" : { "*" : [ " ts3.6/* " ] }
}
}
유형 디렉터리(이 예에서는 ts3.6/
) 내부의 typesVersions
필드에 언급된 하위 디렉터리를 만듭니다. ts3.6/
TypeScript 버전 3.6 이하를 지원하므로 기존 유형과 테스트를 거기에 복사하세요.
패키지 루트로 돌아가서 사용하려는 TypeScript 3.7 기능을 추가하세요. 사람들이 패키지를 설치하면 TypeScript 3.6 이하는 ts3.6/index.d.ts
에서 시작되는 반면 TypeScript 3.7 이상은 index.d.ts
에서 시작됩니다.
예를 들어 블루버드(bluebird)를 볼 수 있습니다.
이는 TypeScript-DOM-lib-generator에 속할 수 있습니다. 거기의 지침을 참조하세요. 표준이 아직 초안인 경우 여기에 속합니다. dom-
으로 시작하는 이름을 사용하고 표준에 대한 링크를 package.json
의 "프로젝트" 링크로 포함합니다. 초안 모드가 종료되면 이를 명확히 입력된 항목에서 제거하고 관련 @types
패키지를 더 이상 사용하지 않을 수 있습니다.
참고: 이 섹션의 논의에서는 의미론적 버전 관리에 익숙하다고 가정합니다.
각각의 명확한 유형 패키지는 npm에 게시될 때 버전이 지정됩니다. 확실히 Typed-tools( @types
패키지를 npm에 게시하는 도구)는 package.json
에 나열된 major.minor.9999
버전 번호를 사용하여 선언 패키지의 버전을 설정합니다. 예를 들어, 다음은 이 글을 쓰는 당시 버전 20.8.x
에 대한 Node 유형 선언의 처음 몇 줄입니다.
{
"private" : true ,
"name" : " @types/node " ,
"version" : " 20.8.9999 "
}
버전이 20.8.9999
로 나열되므로 @types/node
패키지의 npm 버전도 20.8.x
입니다. package.json
의 버전에는 major.minor
버전(예: 10.12
)과 .9999
만 포함되어야 합니다. 이는 라이브러리 패키지와 유형 선언 패키지 간에 주 릴리스 번호와 부 릴리스 번호만 정렬되기 때문입니다. ( .9999
는 로컬 개발 중에 로컬 @types
패키지가 항상 최신인지 확인하기 위한 것입니다.) 유형 선언 패키지의 패치 릴리스 번호(예: 20.8.0
의 .0
)는 한정적 유형에 의해 0으로 초기화되고 매번 증가됩니다. 해당 라이브러리의 동일한 주/부 버전에 대해 새로운 @types/node
패키지가 npm에 게시됩니다.
때로는 유형 선언 패키지 버전과 라이브러리 패키지 버전이 동기화되지 않을 수 있습니다. 다음은 도서관 사용자에게 얼마나 불편을 끼치는지에 대한 몇 가지 일반적인 이유입니다. 일반적으로 마지막 경우에만 문제가 있습니다.
@types
패키지 간의 버전이 일치하는지 확인하면 일반적으로 npm update
작동합니다. ❗ 라이브러리에 대한 유형 선언을 업데이트하는 경우 항상 package.json
의 major.minor
버전을 문서화하는 라이브러리 버전과 일치하도록 설정하세요! ❗
의미 체계 버전 관리에서는 주요 변경 사항이 있는 버전에서 주 버전 번호를 늘려야 합니다. 예를 들어, 3.5.8
릴리스 이후에 공개적으로 내보낸 함수를 제거하는 라이브러리는 다음 릴리스에서 해당 버전을 4.0.0
으로 올려야 합니다. 또한 라이브러리의 4.0.0
릴리스가 출시되면 라이브러리 API에 대한 주요 변경 사항을 포함하여 확실히 형식화된 유형 선언 패키지도 4.0.0
으로 업데이트해야 합니다.
많은 라이브러리에는 주요 변경 사항이 있는 새 버전으로 즉시 이동하지 않는 대규모 개발자(해당 라이브러리를 종속성으로 사용하는 다른 패키지의 관리자 포함)가 설치되어 있습니다. 관리자가 다시 작성할 시간을 갖기까지 몇 달이 걸릴 수 있기 때문입니다. 새 버전에 적응하기 위한 코드입니다. 그동안 이전 라이브러리 버전 사용자는 여전히 이전 버전의 유형 선언을 업데이트하기를 원할 수 있습니다.
이전 버전의 라이브러리 유형 선언을 계속 업데이트하려는 경우 현재(곧 "이전" 버전이 될 예정) 버전의 이름을 딴 새 하위 폴더(예: /v2/
)를 만들고 현재 버전의 기존 파일을 해당 폴더로 복사할 수 있습니다. .
새 버전 폴더를 생성할 때 package.json
의 버전 필드가 업데이트되었는지 확인하세요. pnpm
필요할 때마다 이 버전의 패키지를 자동으로 확인합니다. 저장소의 다른 패키지가 이 새 버전에 의존해야 하는 경우 해당 package.json
도 업데이트되었는지 확인하세요.
예를 들어 types/history/v2
생성하는 경우 package.json
은 다음과 같습니다.
{
"private" : true ,
"name" : " @types/history " ,
"version" : " 2.4.9999 "
}
다른 패키지는 다음을 지정하여 이 버전을 선택할 수 있습니다.
{
"private" : true ,
"name" : " @types/browser-sync " ,
"version" : " 2.26.9999 " ,
"dependencies" : {
"@types/history" : " ^2 "
}
}
또한 /// <reference types=".." />
경로 매핑에서 작동하지 않으므로 종속성은 import
사용해야 합니다.
@types
패키지는 항상 동일한 버전의 패키지를 입력하므로 @types/[email protected]
는 [email protected]
입니다. 결과적으로, 주요/사소한 범프와 함께 대상 패키지 버전을 변경하는 경우를 제외하고(우연 여부에 관계없이) 모든 변경 사항은 패치 개정판으로 게시됩니다.
주요 변경 사항과 관련하여 DT 유지관리자는 패키지의 인기, 제안된 주요 변경 사항의 장점, 사용자가 코드를 수정하는 데 필요한 노력, 변경 사항이 동기화될 수 있을 때까지 합리적으로 지연될 수 있는지 여부를 고려합니다. 업스트림 라이브러리에 큰 변화가 생겼습니다.
TypeScript 핸드북에는 정의 작성에 대한 훌륭한 일반 정보가 포함되어 있으며 ES6 스타일 모듈 구문을 사용하여 정의를 생성하는 동시에 전역 범위에서 사용할 수 있는 객체를 지정하는 방법을 보여주는 이 예제 정의 파일도 포함되어 있습니다. 이 기술은 웹 페이지의 스크립트 태그를 통해 전역적으로 로드하거나 require 또는 ES6 스타일 가져오기를 통해 가져올 수 있는 라이브러리인 big.js
의 정의에서 실제로 입증됩니다.
전역적으로 참조되거나 가져온 모듈로 정의가 어떻게 사용될 수 있는지 테스트하려면 test
폴더를 만들고 거기에 두 개의 테스트 파일을 배치합니다. 하나의 이름을 YourLibraryName-global.test.ts
로 지정하고 다른 하나는 YourLibraryName-module.test.ts
. 전역 테스트 파일은 라이브러리가 전역 범위에서 사용 가능한 웹 페이지에 로드된 스크립트에서 사용되는 방식에 따라 정의를 실행해야 합니다. 이 시나리오에서는 import 문을 지정하면 안 됩니다. 모듈 테스트 파일은 가져올 때 사용되는 방법에 따라 정의를 실행해야 합니다( import
문 포함). tsconfig.json
파일에 files
속성을 지정하면 두 테스트 파일을 모두 포함해야합니다. 이것의 실질적인 예는 big.js
정의에서도 사용할 수 있습니다.
각 테스트 파일에서 정의를 완전히 연습 할 필요는 없습니다. 글로벌 테스트 파일에서 전 세계적으로 액세스 가능한 요소 만 테스트하고 모듈 테스트 파일의 정의를 완전히 연습하거나 그 반대도 마찬가지입니다.
스코핑 된 패키지의 유형 @foo/bar
types/foo__bar
로 이동해야합니다. 이중 밑줄에 주목하십시오.
이 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다.
정의 파일의 저작권은 각 정의 파일의 시작 부분에 나열된 각 기고자의 각각입니다.