私は常にフラグを使用して TypeScript をコンパイルします--noImplicitAny
。これは、型チェックをできるだけ厳密にしたいので理にかなっています。
問題は、次のコードでエラーが発生することです。
Index signature of object type implicitly has an 'any' type
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
注目すべき重要な点は、キー変数はアプリケーション内の別の場所から取得され、オブジェクト内の任意のキーになる可能性があるという考え方です。
次のようにして型を明示的にキャストしてみました:
let secondValue: string = <string>someObject[key];
それとも、私のシナリオは では不可能なのでしょうか--noImplicitAny
?
ベストアンサー1
インデックス署名を追加すると、TypeScript にその型が何であるかがわかるようになります。
あなたの場合は[key: string]: string;
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
[key: string]: string;
}
ただし、これにより、すべてのプロパティ タイプがインデックス シグネチャと一致するように強制されます。すべてのプロパティが a であるため、string
これは機能します。
インデックス署名は配列と「辞書」パターンを記述する強力な方法ですが、すべてのプロパティが戻り値の型と一致することも強制します。
編集:
型が一致しない場合は、ユニオン型を使用できます[key: string]: string|IOtherObject;
ユニオン型の場合は、型を定義するのではなく、TypeScript に型を推測させる方が適切です。
// Type of `secondValue` is `string|IOtherObject`
let secondValue = someObject[key];
// Type of `foo` is `string`
let foo = secondValue + '';
ただし、インデックス シグネチャにさまざまな型が多数ある場合は、少し面倒になる可能性があります。その代替案は、any
シグネチャで を使用することです[key: string]: any;
。その場合、上記のように型をキャストする必要があります。