日本語
  • typescript
  • javascript
  • nodejs
  • node_modules
  • module-augmentation

TypeScript モジュールの拡張とネストされた JavaScript ファイルの処理

TypeScript におけるモジュールの拡張の基本と、ネストされた JavaScript ファイルに型定義を追加する方法を学びます。

Gao
Gao
Founder

TypeScript は、JavaScript コードに型の安全性を提供する能力のおかげで、10 年以上にわたり JavaScript エコシステムに貴重な追加機能をもたらし、その人気を高めてきました。

JavaScript パッケージの型

後方互換性と柔軟性のために、TypeScript はパッケージの作者に対して、彼らの JavaScript パッケージのための型定義を提供することを許可します。そのような型定義は通常、"DefinitelyTyped" リポジトリに保存されています。これらの型定義は @types スコープを使用してインストールできます。例えば、@types/react は React パッケージのための型定義です。

これらの型定義をインストールした後は、型の安全性を確信してパッケージを使用できます。型安全性を持って React コンポーネントを定義する例を見てみましょう:

モジュールの拡張

人気のある JavaScript パッケージのほとんどには @types スコープで利用可能な型定義がありますが、中には型定義がない、もしくは型定義が古いパッケージも存在します。そのような場合、TypeScript は「モジュールの拡張」という強力な機能を提供して、これらのパッケージに型定義を追加できます。例を見てみましょう:

この拡張された型定義をコード内で使用することができます:

モジュールの拡張は、パッケージの型定義を追加するだけでなく、既存の型定義を拡張することも可能です。例えば、window オブジェクトに新しいプロパティを追加することができます:

そして、それをコード内で使用します:

以前の記事で、React Router ライブラリの型の問題について話しましたが、既存の型を拡張し、カスタム宣言ファイルを通じて拡張することで、その影響を克服する必要がありました。

モジュールの拡張を使用する際には、型定義の正確性を JavaScript のソースコードを慎重に検査することによって確保することが重要です。間違った型定義はランタイムエラーを引き起こす可能性があります。上記の例では、window.foo プロパティは、window オブジェクト上に存在する文字列でなければなりません。

グローバル拡張

時にはグローバル変数を導入するスクリプトに遭遇することがあり、そのグローバル変数の型定義を行い TypeScript コード内で使用したいと思うかもしれません。例えば、__DEV__ というグローバル変数を設定するスクリプトがある場合:

このグローバル変数に対して、以下のように型定義を追加することができます:

これで TypeScript コード内で使用できます:

モジュール拡張とグローバル拡張を組み合わせることで、JavaScript プロトタイプの型定義を拡張することもできますが、これは一般的には推奨されていません。グローバルスコープの汚染につながる可能性があるためです。

モジュール拡張の力によってこのような拡張が可能になりますが、グローバルスコープの汚染を防ぐために注意を払うべきです。

ネストされた JavaScript ファイル

先に述べた例では、パッケージのエントリーファイルを通じてインポートが解決できることを前提としていました。しかし、一部のパッケージは、対応する型定義なしにネストされた JavaScript ファイルをエクスポートすることがあります。次の構造を持つ foo というパッケージを考えてみましょう:

foo パッケージは index.js ファイルをエントリーポイントとしてエクスポートし、同時に bar ディレクトリもエクスポートします。

foo パッケージの型定義を拡張するには、foo.d.ts ファイルを作成します:

ただし、TypeScript で baz.js ファイルをインポートしようとすると、エラーが発生します:

baz.js ファイルの型定義を拡張するには、別の baz.d.ts ファイルを作成する必要があります:

これにより、TypeScript はモジュールとその関連する型定義を見つけることができます:

型定義を整理して保つために、型定義ファイル内でパッケージの構造を模倣することができます:

このアプローチにより、ネストされた JavaScript ファイルを処理する際にも、TypeScript コードの構造を整理し、型安全に保つことができます。