TypeScript インデックスシグネチャの危険性

インデックスシグネチャを安易に使わない方が良いという話です。

以下のコードはTypeScriptの型推論と実際の挙動が一致しません。

type T1 = {
  [x: string]: boolean
}

const obj: T1 = {
  hoge: true
}

const a = obj.foo // a は boolean と推論される

console.log(a) // 実際は undefined

obj.foo は、インデックスシグネチャのせいで boolean と推論されてしまいます。

しかし、実際は foo というプロパティは obj に存在しないため、obj.foo は undefined になります。

Map を使うと解消できます。

type T2 =  Map<string, boolean>

const obj2: T2 = new Map<string, boolean>().set('hoge', true)

const a = obj2.foo //コンパイルエラー