Programmingフロントエンド開発者

TypeScriptにおける拡張タイプ(インデックスシグネチャ)のメカニズムはどのように機能しますか?それは何に使われ、どのような注意点があり、そのような構造を設計する際のリスクは何ですか?

Hintsage AIアシスタントで面接を突破

回答。

問題の歴史

TypeScriptは、すべてのキーを事前に定義することができない場合に、動的なプロパティ名を持つオブジェクトを記述することを許可します。これには、変数オブジェクトの型付けのための方法として登場したインデックスシグネチャが使用されます(マップ、外部サーバーのデータなど)。

問題

インデックスシグネチャがない場合、オブジェクトは事前に指定されたキーのみで認識され、他のキーはコンパイルエラーを引き起こします。同時に、シグネチャの不適切な宣言は、オブジェクトのすべてのプロパティのタイプを曖昧にし、タイプの厳密さを低下させ、バグを引き起こす可能性があります。

解決策

明示的にインデックスシグネチャを宣言するのは、正当化される場合のみ行ってください。文字列キーに基づいたオブジェクトの配列の型付けには、次の形式を使用してください:

コードの例:

interface Dictionary { [key: string]: number; length?: number; } const sample: Dictionary = { apples: 4, oranges: 10 }; sample['bananas'] = 6;

主な特徴:

  • 任意のキーを持つコレクションを記述できる
  • すべての要素の値の型は同じである
  • シグネチャのため、すべての追加プロパティはこの型に一致する必要があります

クイズ風の質問。

インデックスシグネチャで異なるキーに異なる値の型を指定できますか?

いいえ、タイプはすべてのキーのセットで同じである必要があります。もし[key: string]: numberを指定した場合、sample.lengthもnumberでなければなりません:これはインデックスシグネチャと既知のプロパティを併用する場合によくエラーを引き起こします。

インデックスシグネチャをシンボル(symbol)で使用できますか?

はい、ES6以降TypeScriptはシンボルによるインデックスシグネチャをサポートしています:

interface SymbolMap { [key: symbol]: string; }

インデックスシグネチャを持つオブジェクトを、異なる型の追加プロパティと共に宣言するとどうなりますか?

プロパティの型がインデックスシグネチャで宣言された値の型と互換性がない場合、コンパイラはエラーを出します。これはユニオンタイプを使用するか、そのようなフィールドを別のインターフェースに移動することで回避できます。

型のエラーとアンチパターン

  • 厳格なインターフェースの代わりにインデックスシグネチャの過剰使用
  • オブジェクトの型の曖昧さ
  • 既知のプロパティとインデックスプロパティの不適切な組み合わせ

実生活の例

ネガティブケース

サーバーからの任意の応答にインターフェース{[key: string]: any}が使用されており、データ構造の制御を失うことで予期しないバグを引き起こしました。

利点:

  • ユニバーサル性

欠点:

  • オブジェクト内部での厳格な型付けの完全な喪失
  • 隠れたバグ、プロダクションでの「サプライズ」

ポジティブケース

辞書に対してのみインデックスシグネチャを厳密に使用し、既知のプロパティにはシグネチャの外で型を明示的に宣言します。

利点:

  • コレクション/マップの明確な構造
  • 既知のフィールドのための厳格な型付けが保存される

欠点:

  • オブジェクトの正しいアーキテクチャの設計にもっと多くの時間が必要