0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

インデックスシグネチャとは、オブジェクトの型を宣言する際に使用できる構文で、任意のプロパティキーに対して、プロパティの型を設定することができます。

オブジェクトの型を宣言するときにはプロパティのキー名が必要になりますが、プロパティに変数を使ってアクセスする場合など、型を宣言する時点ではプロパティキーがなにか判明していない場面などで有用です。

{[key: T]: U}という構文で表され、プロパティキーの型Tとプロパティ値の型Uを設定できます。

Mapped Types の構文{ [key in T]: U } と見かけが似ているので、混同しないよう注意が必要です。

type Fish = {
  [name : string]: string
}

上の例のFish型は、プロパティキー、プロパティ値がともにstring型であるオブジェクト型となっています。

number型のプロパティ値をもつオブジェクトリテラルをFish型の変数に代入しようとすると、以下のようにstring型に合致していない旨の型エラーを出してくれます。

const fish: Fish = {
  name: 'Tuna',
  age: 20
}
Type 'number' is not assignable to type 'string'.(2322)
input.tsx(2, 3): The expected type comes from this index signature.

通常のプロパティと一緒に使う

インデックスシグネチャは通常のプロパティと一緒にオブジェクト型の記述に使用可能です。
ただし、使用できるプロパティには、インデックスシグネチャで指定した型の部分型という制約がつきます。

type Fish = {
  [name : string]: string
  habitat: 'sea' | 'river'
}

sea|river型はstring型の部分型ですので、上の例では問題なく使用できます。
インデックスシグネチャのみのままでも型エラーは出ないのですが、プロパティのキー名で指定することによってFish型の値がhabitatプロパティを必ず持っていなければならないことを型で明示できるので、より厳格な型チェックができるようになっています。

type Fish = {
  [name : string]: string
  age: number
}

一方で上の例のように、インデックスシグネチャの型に合致しないnumber型のプロパティageを追加することはできません。

Property 'age' of type 'number' is not assignable to 'string' index type 'string'.(2411)

型安全性が損なわれるケースに注意

インデックスシグネチャはプロパティ名の判明していないプロパティを型に入れるときなどに有用ではありますが、型安全性を損なう面を持ち合わせていることを意識しておく必要があります。

インデックスシグネチャではプロパティ名を指定せずに型が定義できるので、存在しないプロパティへアクセスした場合にも型エラーが出ないといったことが起こり得ます。

以下のように存在しないプロパティへstring型の変数でアクセスするコードを考えてみます。

type Fish = {
  [name : string]: string
  habitat: 'sea' | 'river'
}

const fish: Fish = {
  name: 'Tuna',
  habitat: 'sea'
}

const key = 'foo'

console.log(fish.key)
console.log(fish.bar)

Fish型の変数fishにはfooというプロパティは存在しないのですが、インデックスシグネチャによって任意のstring型のプロパティキーをもつことが認められているため、存在しないプロパティへのアクセスを型エラーで検知できなくなってしまっています。

インデックスシグネチャには以上のような型安全性を損なう面もあるため、使用に際しては注意が必要です。

インデックスシグネチャが必要になった際には、より安全な方法としてMapの使用を検討してみてもいいかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?