😇

TypeScript ブランケット記法でインデックスシグネチャエラー

2022/05/05に公開

はじめに

オブジェクトのプロパティにアクセスする際にブランケット記法を使うと、
動的なキーを使用してアクセスすることができます。
ただAPIからのレスポンスに対してプロパティにアクセスしたいという場面で
No index signatureエラーがでてしまいハマったので対応をまとめてみます。

インデックスシグネチャとは

オブジェクトがどのようなキーをとるかを示すための型アノテーションです。
{[key: T]: U} のように指定をします。
このオブジェクトは型Tのすべてのキーは、型Uの値を持たなければいけない、という意味になります。
また、型Tにはnumberかstring型のどちらかが使用できます。

やりたいこと

構造がわからないオブジェクトに対して、任意のキーを使用してプロパティにアクセスする、が今回のやりたいことです。
イメージとしては下記のように任意のオブジェクトとキーでアクセスしようとするとコンパイルエラーがでてしまいます。

const returnPersonData = (obj: object, key: string): any => {
  console.log(obj[key]);
};
型 'string' の式を使用して型 '{}' にインデックスを付けることはできないため、要素は暗黙的に 'any' 型になります。
型 'string' のパラメーターを持つインデックス シグネチャが型 '{}' に見つかりませんでした。

objに対してkeyが存在するかどうかTypeScriptはわからないため、エラーとなってしまっています。

やったこと

objの型に{[key: T]: U}を指定するようにしました。

const returnPersonData = (obj: {[anyKey: string]: any}, key: string): any => {

今回オブジェクトの構造がまったく予測できないため、anyを使用しました。
型安全面から見てanyは使いたくないのですが見つからなかったためこちらの方法にしました。
(anyの替わりにstring | number | boolean | objectも使えますがそこまで絞り込めない且つ冗長なのでanyにしました。)

まとめ

他の方法がありそうな気はします...
他に良い方法ないか調べてみます。

参考

https://www.oreilly.co.jp/books/9784873119045/

Discussion