🕌
インデックスシグネチャ
インデックスシグネチャとは
今回の記事はオブジェクト型の型アノテーションの一つであるインデックスシグネチャについてまとめます。
インデックスシグネチャの定義は
{[key:T]:U}
・・・このオブジェクトについては型Tの全てのキー(プロパティ名)は、型Uの値を持たなければならないことを意味します。
type MovietheatreSeatingAssigment = {
[seatNUmber: string]: string;
};
const users: MovietheatreSeatingAssigment = {
k12: "Max",
k13: "Green",
k14: "Jon",
};
このケースは映画館の座席の割当についてのオブジェクトです。型エイリアスによるオブジェクト型の型注釈によって、オブジェクトから1つ1つキーと値の型を定義するのはあまりに面倒です。
インデックスシグネチャを使うことで、オブジェクトがより多くのキーを含む可能性があることをTypescript
に伝える事ができます。
インデックスシグネチャの注意点
①キーの型はstring型かnumber型
先程はキーの型がstringでしたがnumber型も可能です。
type Ranking = {
[rank: number]: string;
};
const ranking: Ranking = {
1: "Mikasa Ackermann",
2: "Reiner Brown",
3: "Bertolt Hoover",
};
②キーの型が同じシグネチャを重複することはできない
プロパティ名が異なる場合でも、その型が同じであればエラーが起きます。
interface Ranking {
[rank: number]: string;
[notRanked:number]:string//エラー(number インデックス シグネチャが重複しています。)
}
キーの型を変えればエラーは生じません。
type Ranking = {
[rank: number]: string;
[notRanked: string]: string;
};
const ranking: Ranking = {
1: "Mikasa Ackermann",
2: "Reiner Brown",
3: "Bertolt Hoover",
"104期生": "Armin Harlert",
};
③value(値)の型は揃える
インデックスシグネチャが重複する場合、キーの型は異なる必要があったのに対し、valueの型は揃える必要がありました。(直前のコード参照)
またインデックスシグネチャを利用するケースは以下のようなことも可能です。ここでもvalueの型は揃える必要があります。
type Obj = {
belongs: string;
[key: string]: string;
} //valueの型はどちらもstring
const person1: Obj = {
belongs: "Research Corps",
name: "Eren Jaeger",
birthdata: "3/30",
};
その他の気づき
直前の例ですが、以下のようなオブジェクトの定義でもエラーは生じません。
type Obj = {
belongs: string;
[key: string]: string;
};
const person1: Obj = {
belongs: "Research Corps",
};
インデックスシグネチャによる型注釈を完全に無視したコードです。ここから考察するに、インデックスシグネチャを定義する裏ではオプション?
が付くというイメージでしょうか。
またオブジェクト型を宣言する時に使用できる修飾子であるreadonlyは,インデックスシグネチャにも利用可能です。
type Ranking = {
readonly [rank: number]: string;
};
const ranking: Ranking = {
1: "Mikasa Ackermann",
2: "Reiner Brown",
3: "Bertolt Hoover",
};
ranking[0] = "Eren Jaeger";
//エラー(型 'Ranking' のインデックス シグネチャは、読み取りのみを許可します。)
Discussion
丁寧にまとめてくださりありがとうございます!
補足ですが、TypeScript 4.4 変更点 まとめによるとTypeScript 4.4からsymbolやTemplate Literal Typesがインデックスシグネチャで利用できるようになったようです。
実行結果は以下の通りです。
参考: