高品質のTypeScript 型定義のリポジトリ。
この README は、スペイン語、한국어、Русский、简体中文、ポルトガル語、イタリア語、日本語、フランス語でも読むことができます。
管理者マニュアルへのリンク
Definitely Typed は最近、適切なpnpm
モノリポジトリに変更されました。このリポジトリ内のパッケージのレイアウトの変更については、このドキュメントを読み直してください。
少なくとも、リポジトリ (Windows の場合は、 node ./scripts/clean-node-modules.js
) git clean -fdx
て、 node_modules
クリーンアップし、 pnpm install --filter .
ワークスペースのルートをインストールします。 pnpm install
の詳細については、以降のセクションを参照してください。
このセクションでは、リポジトリと公開プロセスの健全性を追跡します。これは、PR やパッケージに問題がある貢献者にとって役立つかもしれません。
ここで何かが間違っていると思われる場合、または上記のいずれかが失敗している場合は、TypeScript コミュニティ Discord サーバーの Definitely Typed チャネルでお知らせください。
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 で書かれている場合は、Definitely Typed に公開する代わりに、生成された宣言ファイルをパッケージにバンドルします。型注釈に 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
またはテストのいずれかで参照されていることを確認してください。
Definitely Typed メンバーは定期的に新しい PR を監視していますが、他の PR の数が多いと処理が遅くなる可能性があることに留意してください。
パッケージの良い例については、「base64-js」を参照してください。
パッケージが独自の型をバンドルする場合、混乱を避けるために、Definitely Typed から型を削除する必要があります。
これを削除するには、 pnpm run not-needed <typingsPackageName> <asOfVersion> [<libraryName>]
を実行します。
<typingsPackageName>
: これは、削除するディレクトリの名前です。<asOfVersion>
: スタブはこのバージョンで@types/<typingsPackageName>
に公開されます。現在公開されているバージョンよりも上位である必要があり、npm の<libraryName>
のバージョンである必要があります。<libraryName>
: Definitely Typed 型を置き換える npm パッケージの名前。通常、これは<typingsPackageName>
と同じですが、その場合は省略できます。パッケージが Definitely Typed に含まれていない場合は、 notNeededPackages.json
に追加する必要はありません。
pnpm test <package to test>
を実行して変更をテストします。 <package to test>
はパッケージの名前です。個々の package.json ではテスト スクリプトが定義されていないため、これを DefinitelyTyped ディレクトリから実行する必要があります。
このスクリプトは、dtslint を使用して、dts ファイルに対して TypeScript コンパイラーを実行します。
すべての変更の準備ができたら、 pnpm run test-all
使用して、変更が他のモジュールにどのような影響を与えるかを確認します。
attw
) チェックdtslint には、@arethetypeswrong/cli からのモジュール形式とpackage.json
構成チェックが含まれています。チェックは、DefinitelyTyped パッケージと比較するために、SemVer メジャー互換の実装パッケージが npm で見つかる場合にのみ実行されます。 ( package.json
でnonNpm
としてマークされている DefinitelyTyped パッケージはスキップされます。)
現在、多くのパッケージがattw
チェックに失敗するため、修正する必要があります。漸進的な進歩を可能にするために、パッケージがattw.json
のfailingPackages
にリストされている場合、失敗したattw
チェックはdtslint
の実行に失敗しませんが、それらはpnpm test my-package
出力で報告されます。パッケージを修正する場合は、 attw
チェックで失敗したdtslint
実行を開始できるように、そのパッケージをfailingPackages
から削除します。
attw
によって報告されたすべての問題には、出力内にリンクされたドキュメントが含まれています。問題を回避するためのいくつかの経験則:
実装パッケージがpackage.json
でそれらを使用する場合、 DefinitelyTyped パッケージのpackage.json
には、一致するtype
フィールドと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 "
}
}
}
その場合、DefinitelyTyped 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 = ...
使用する場合、DefinitelyTyped パッケージは、 export default
ではなく、 export =
を使用する必要があります。 (あるいは、 module.exports
が名前付きプロパティの単なるオブジェクトである場合、DefinitelyTyped パッケージは一連の名前付きエクスポートを使用できます。) この問題を解決する際の最も一般的な障害は、プライマリ エクスポートに加えて型をエクスポートする方法についての混乱です。たとえば、次のタイプが誤って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 コミュニティ Discord サーバーの DefinitelyTyped チャネルで質問してください。
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
<my-package>-tests.ts
ファイルが存在する必要があります。これは、インポートされる*.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 の Readme を参照してください。
.eslintrc.json
何らかの理由で lint ルールを無効にする必要がある場合は、特定の行に対して無効にします。
// 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
TL;DR: 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
でのインポートのコンパイル時の有効性は、その型のユーザーが継承しない特定のコンパイル設定に依存するため、DefinitelyTyped でこのパターンを使用すると、ユーザーは独自のコンパイル設定を変更する必要があり、これは正しくない可能性があります。ランタイムのために。代わりに、構成に依存しない広範な互換性を確保するには、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
以外の依存関係を、許可される外部依存関係のリストに追加する必要があります。ピカデイが良い例です。これらの追加はメンテナーによって承認されるため、 @types
パッケージが悪意のあるパッケージに依存していないことを確認する機会が得られます。
実装パッケージが ESM を使用し、 "type": "module"
を指定する場合は、以下と一致するように package.json を変更する必要があります。
{
"type" : " module "
}
これは、実装パッケージの package.json にexports
がある場合にも当てはまります。
Definitely Typed ではpackage.json
でpeerDependencies
が許可されます。ピアの依存関係は、パッケージ マネージャーが予期せず新しすぎるバージョンをインストールしたり、同じパッケージの複数のバージョンをインストールしたりする状況を防ぐのに役立ちます。ただし、ピアの依存関係には欠点もあります。パッケージマネージャーは、ピアの依存関係の処理が異なります (たとえば、 yarn
ピアの依存関係を自動インストールしませんnpm
不一致のために--legacy-peer-deps
必要とします)。そのため、新しいピア依存関係を導入する PR にはメンテナの承認が必要であり、特定の状況に限定する必要があります。
一般に、タイプ パッケージは、アップストリーム パッケージが同じパッケージ (またはそのタイプ) に対してピア依存関係を持つ場合にのみ、ピア依存関係を持つ必要があります。たとえば、React コンポーネントの DT パッケージは@types/react@*
に対するピア依存関係を指定できます。これは、コンシューマーが JSX を使用するには、最初に@types/react
インストールする必要があるためです。コンシューマがプロジェクトに@types/react@16
インストールしているが、新しいバージョンの@types/react
が npm で利用できる場合、ピアの依存関係により、パッケージ マネージャーがその新しいバージョンの代わりに@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
パッケージにどのファイルを含めるかを定義します。それは特定の形式をとる必要があります。リポジトリ内にバージョンが 1 つだけあるパッケージの場合:
*
! ** / * .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
(または他のエディターの同等のもの) を使用して、VS Code dprint 拡張機能を使用して保存時にフォーマットすることを検討してください。function sum(nums: number[]): number
: 関数がパラメータに書き込まない場合は、 ReadonlyArray
を使用します。interface Foo { new(): Foo; }
: これは、新規作成可能なオブジェクトのタイプを定義します。おそらく、 declare class Foo { constructor(); }
.const Class: { new(): IClass; }
: クラス宣言の使用を優先しますclass Class { constructor(); }
新しい可能定数の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
になります。 string | object
。注意:
.github/CODEOWNERS
変更しないでください。常にpackage.json
内の所有者のリストを変更してください。
DT には、特定のモジュールのタイプの品質を維持したい人々である「定義所有者」という概念があります。
自分自身を定義所有者として追加するには、 package.json
のowners
配列を変更します。
"owners" : [
{
"name" : " Some Person " ,
"githubUsername" : " somebody "
},
{
"name" : " Some Corp " ,
"url" : " https://example.org "
}
]
このリストは、貢献に対するクレジットを提供するために使用されるものではないことに注意してください。 PR レビューの管理にのみ使用されます。
週に 1 回、定義所有者は、信頼できる情報源である .github/CODEOWNERS ファイルに同期されます。
Definitely Typed は、GitHub 上で最もアクティブなリポジトリの 1 つです。このプロジェクトがどのようにして生まれたのか疑問に思ったかもしれません。 @johnnyreilly が Definitely Typed の歴史を書きました。これは、@barisyankov によって作成されたリポジトリから、TypeScript エコシステムの重要な部分になるまでの Definitely Typed の初期の物語を語っています。 Definitely Typed のストーリーはここで読むことができます。
@types
パッケージの間には正確にどのような関係があるのでしょうか? DefinitelyTyped-tools のおかげで、 master
ブランチは npm の@types
スコープに自動的に公開されます。
状況によりますが、ほとんどのプル リクエストは 1 週間以内にマージされます。一部の PR はモジュールの所有者によってマージでき、より高速にマージできます。だいたい:
モジュールのタイプのみを変更し、対応するテストの変更を含む PR は、はるかに高速にマージされます。
定義のpackage.json
にリストされている所有者によって承認された PR は通常、より迅速にマージされます。新しい定義の PR には、メンテナによるさらなるレビューが必要となるため、さらに時間がかかります。各 PR はマージされる前に TypeScript または Definitely Typed チーム メンバーによってレビューされます。人的要因により遅延が発生する可能性があるため、しばらくお待ちください。新しいプル リクエスト ステータス ボードをチェックして、メンテナが開いている PR を処理する際の進捗状況を確認します。
npm で毎週何百万ものダウンロードがある Node/Express/Jest など、非常に人気のあるモジュールへの変更の場合、コントリビューションの要件は少し高くなります。これらのプロジェクトへの変更は、生態系に多大な影響を与える可能性があるため、私たちはプロジェクトへの変更を細心の注意を払って扱います。これらのモジュールには、DT メンテナからの承認とモジュール所有者からの熱心なサポートの両方が必要です。これを通過するためのハードルは非常に高く、多くの場合、チャンピオンがいないために PR が陳腐化する可能性があります。誰もコミットしていないことに気付いた場合は、PR の焦点を小さくしてみてください。
@types
npm パッケージはいつ更新されますか?npm パッケージは 1 時間以内に更新されるはずです。 1 時間以上経過している場合は、TypeScript Community Discord サーバーの Definitely Typed チャネルで PR 番号を言及すると、現在のメンテナが適切なチーム メンバーに調査を依頼します。
<reference types="" />
またはインポートを使用する必要がありますか?参照しているモジュールがモジュール ( export
を使用) の場合は、import を使用します。参照しているモジュールがアンビエント モジュール ( declare module
を使用) である場合、またはグローバルを宣言しているだけの場合は、 <reference types="" />
を使用します。
"noImplicitAny": true
、 "noImplicitThis": true
または"strictNullChecks": true
が欠落しているtsconfig.json
があります。そうすると、彼らは間違っているのですが、私たちはまだそれに気づいていません。それらを修正するには、プル リクエストを送信してください。
はい、dprint を使用します。エディターには dprint 拡張機能を使用することをお勧めします。
あるいは、コードを自動的にフォーマットする git フックを有効にすることもできます。 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 拡張機能をリポジトリ内のデフォルトのフォーマッタとして設定します。
現在要求されている定義は次のとおりです。
型が Web 標準の一部である場合は、デフォルトのlib.dom.d.ts
の一部にできるように、型を TypeScript-DOM-lib-generator に提供する必要があります。
ソース JavaScript コードがまったくない場合、たとえばヘルパー型や仕様の型を作成している場合は、Definitely Typed ではなく自分で型を公開する必要があります。 @types
パッケージは既存の JavaScript コードに型を提供することを目的としているため、直接インポートすることは意図されていません。つまり、 import type { ... } from "@types/foo"
ように使用することを目的とした Definitely Typed パッケージを作成しないでください。また、 foo
がインストールされていないときにimport type { ... } from "foo"
を書き込むことも期待できません。
これは、ブラウザーのみの JavaScript ライブラリに型を提供したり、node、bun などの環境全体に型を提供したりすることとは異なります。そこで、型は暗黙的に解決されるか、 /// <references types="foo" />
を使用して解決されます。
Chai-http などの一部のパッケージは関数をエクスポートします。
ES6 スタイルのインポートを使用してこのモジュールをimport * as foo from "foo";
エラーが発生します:
エラー TS2497: モジュール 'foo' は非モジュール エンティティに解決されるため、この構造を使用してインポートできません。
このエラーは、関数宣言を同じ名前の空の名前空間とマージすることで抑制できますが、この方法はお勧めできません。これは、この問題に関してよく引用される Stack Overflow の回答です。
import foo = require("foo");
を使用してモジュールをインポートする方が適切です。構文。それでも、 import foo from "foo";
2 つのオプションがあります。
--allowSyntheticDefaultImports
コンパイラ オプションを使用できます。--esModuleInterop
コンパイラ オプションを使用できます (TypeScript 2.7 以降)。 export =
使用しますが、私はデフォルトの import を使用することを好みます。 export =
export default
に変更できますか?前の質問と同様に、 --allowSyntheticDefaultImports
または--esModuleInterop
コンパイラ オプションの使用を参照してください。
型定義が正しい場合は変更しないでください。 npm パッケージの場合、 node -p 'require("foo")'
がモジュールのインポートに機能する場合、 export =
は正確であり、node -p 'require("foo").default' がモジュールのインポートに機能する場合、 export default
正確ですnode -p 'require("foo").default'
。
次に、 package.json
で"minimumTypeScriptVersion": "XY"
を指定することで、サポートされる最小バージョンを設定します。
ただし、プロジェクトで、たとえば 3.7 以降と互換性のある型を、3.6 以下と互換性のある型と同時に維持する必要がある場合は、 typesVersions
機能を使用する必要があります。この機能の詳細な説明は、TypeScript の公式ドキュメントで見つけることができます。
始めるための短い例を次に示します。
typesVersions
package.json
に追加する必要があります。
{
"private" : true ,
"types" : " index " ,
"typesVersions" : {
"<=3.6" : { "*" : [ " ts3.6/* " ] }
}
}
types ディレクトリ内に、 typesVersions
フィールドに記載されているサブディレクトリ (この例ではts3.6/
) を作成します。 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
の「プロジェクト」リンクとして含めます。ドラフト モードを卒業すると、Definitely Typed から削除し、関連する@types
パッケージを非推奨にする可能性があります。
注: このセクションの説明は、セマンティック バージョニングに精通していることを前提としています。
各 Definitely Typed パッケージは、npm に公開されるときにバージョン管理されます。 DefinitelyTyped-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
) は、Definitely Typed によってゼロに初期化され、毎回インクリメントされます。新しい@types/node
パッケージは、対応するライブラリの同じメジャー/マイナー バージョンに対して npm に公開されます。
場合によっては、型宣言パッケージのバージョンとライブラリ パッケージのバージョンが同期しなくなることがあります。以下に、一般的な理由を、図書館の利用者にとってどれくらい不便であるか順にいくつか挙げます。通常、問題となるのは最後のケースだけです。
@types
パッケージの間でバージョンが対応していることを確認すれば、通常はnpm update
機能するはずです。 ❗ ライブラリの型宣言を更新する場合は、文書化しているライブラリのバージョンと一致するようにpackage.json
のmajor.minor
バージョンを常に設定してください。 ❗
セマンティック バージョニングでは、重大な変更が含まれるバージョンではメジャー バージョン番号を増やす必要があります。たとえば、 3.5.8
リリース後にパブリックにエクスポートされた関数を削除したライブラリは、次のリリースでバージョンを4.0.0
に上げる必要があります。さらに、ライブラリの4.0.0
リリースがリリースされたら、ライブラリの API に対する重大な変更を含め、Definitely Typed 型宣言パッケージも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 スタイルのモジュール構文を使用して定義を作成する方法を示し、グローバル スコープで使用できるオブジェクトを指定するこのサンプル定義ファイルも含まれています。この手法は、Web ページ上の script タグを介してグローバルにロードしたり、require または ES6 スタイルのインポートを介してインポートしたりできるライブラリであるbig.js
の定義で実際に実証されています。
定義がグローバルに参照される場合とインポートされたモジュールとして使用される場合の両方でどのように使用できるかをテストするには、 test
フォルダーを作成し、そこに 2 つのテスト ファイルを配置します。一方にYourLibraryName-global.test.ts
という名前を付け、もう一方にYourLibraryName-module.test.ts
名前を付けます。グローバルテスト ファイルは、ライブラリがグローバル スコープで利用可能な Web ページにロードされたスクリプトでどのように使用されるかに従って定義を実行する必要があります。このシナリオでは、インポート ステートメントを指定する必要はありません。モジュールテスト ファイルは、インポート時の使用方法 ( import
ステートメントを含む) に従って定義を実行する必要があります。 tsconfig.json
ファイルにfiles
プロパティを指定する場合は、両方のテストファイルを必ず含めてください。これの実用的な例は、 big.js
定義でも利用できます。
各テストファイルで定義を完全に実行する必要はないことに注意してください。グローバルなテストファイルのグローバルにアクセス可能な要素のみをテストし、モジュールテストファイルで定義を完全に実行するか、その逆を完全に行使するだけで十分です。
スコープパッケージ@foo/bar
のタイプは、 types/foo__bar
で移動する必要があります。ダブルアンダースコアに注意してください。
このプロジェクトは MIT ライセンスに基づいてライセンスされています。
定義ファイルの著作権は、各定義ファイルの先頭にリストされている各貢献者のそれぞれのそれぞれです。