TypeScriptのIndex Signature"{[key:string]:string}"で特定の文字だけのIndexを扱う
2019-03-05

TypeScriptのIndex Signature"{[key:string]:string}"で特定の文字だけのIndexを扱う

TypeScriptの小ネタです。

TypeScriptでStringをキーにしてオブジェクトにアクセスする場合、次のようなTypeを定義します。

const user: { [key:string] : string } = { name: "mitsuruog" };

console.log(user["name"]); // => mitsuruog

ただ、このStringでアクセスする部分をもう少し型安心にしたいですね。

StringのキーのセットでTypeを作成して、Index Signatureに適用できると型安心にできそうです。
試しにUnionTypeを使ってみます。

type Index = "name" | "address";

// Error: index signature parameter type cannot be a union type. Consider using a mapped object type instead.
const user: { [key:Index] : string } = { name: "mitsuruog" };

このままでは使えないようなので、Mapped Typesを使ってみます。

type Index = "name" | "address";

// Error: Property 'address' is missing in type '{ name: string; }' but required in type '{ name: string; address: string; }'.
const user: { [key in Index] : string } = { name: "mitsuruog" };

今度は、オブジェクト初期化の時に全てのキーが必要になってしまったようです。なのでIndexをOptionalにします。

type Index = "name" | "address";

const user: { [key in Index]? : string } = { name: "mitsuruog" };

console.log(object2.name);

// Error: Property 'password' does not exist on type '{ name?: string; address?: string; }'.
console.log(object2.password);

存在しないキーでアクセスしようとした時にコンパイラが検知するようになりました。

これで型安心になりました。

参考