1. ホーム
  2. typescript

[解決済み] noImplicitAnyフラグを有効にしてtypescriptをコンパイルすると、"Index signature of object type implicitly has an 'any' type "というエラーが発生しますが、どうすれば防ぐことができますか?

2022-03-15 14:30:54

質問

私はいつも --noImplicitAny というフラグを付けて Typescript をコンパイルしています。これは、型チェックを可能な限り厳しくしたいので、理にかなっています。

私の問題は、次のコードでエラーが発生することです。 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];

重要なのは、key変数がアプリケーションのどこかから来たもので、オブジェクト内のどのkeyでも良いという考え方です。

によって明示的に型をキャストしてみたのですが、どうでしょうか?

let secondValue: string = <string>someObject[key];

それとも、私のシナリオは --noImplicitAny ?

解決方法は?

インデックスシグネチャを追加することで、TypeScriptに型がどうあるべきかを知らせることができます。

あなたの場合、それは [key: string]: string;

interface ISomeObject {
    firstKey:      string;
    secondKey:     string;
    thirdKey:      string;
    [key: string]: string;
}

しかし、これでは、すべてのプロパティタイプがインデックスシグネチャと一致するように強制されます。すべてのプロパティが 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; そして、上でやったように型をキャストする必要があります。