メインコンテンツまでスキップ

オブジェクトからキーの型を生成する

オブジェクトからキーだけ欲しい#

あるメッセージが言語ごとに定義されているとします。

typescript
const conf = {
en: "Are you sure?",
fr: "Êtes-vous sûr?",
es: "Está seguro?",
ja: "よろしいですか?",
zh: "您确定吗?",
};
typescript
const conf = {
en: "Are you sure?",
fr: "Êtes-vous sûr?",
es: "Está seguro?",
ja: "よろしいですか?",
zh: "您确定吗?",
};

内容は確認を促す変哲もないシステムのメッセージです。このオブジェクトを使ってシステムがサポートしている言語の一覧を作ります。次のようなユニオン型が今回の目的です。

typescript
type Language = "en" | "fr" | "es" | "ja" | "zh";
typescript
type Language = "en" | "fr" | "es" | "ja" | "zh";

typeof#

頻出するこの typeof はJavaScriptのものではなく、TypeScriptの typeof です。これをオブジェクトに対して使用している例は前のページにあるとおりです。

この例で実行すれば次のような型 TypeOfLanguage が生成されるでしょう (型名は便宜的なものです) 。

typescript
type TypeOfLanguage = typeof conf;
// ->
// {
// en: string,
// fr: string,
// es: string,
// ja: string,
// zh: string
// };
typescript
type TypeOfLanguage = typeof conf;
// ->
// {
// en: string,
// fr: string,
// es: string,
// ja: string,
// zh: string
// };

ここまでくればあとは少しです。 TypeOfLanguage 型のキーだけを型にしてしまいます。

keyof#

kyeof はオブジェクトの型に使うとそのオブジェクトのキーをユニオン型にして返します。上記の TypeOfLanguage 型があれば

typescript
type Langauge = keyof TypeOfLanguage;
// -> 'en' | 'fr' | 'es' | 'ja' | 'zh';
typescript
type Langauge = keyof TypeOfLanguage;
// -> 'en' | 'fr' | 'es' | 'ja' | 'zh';

となります。

まとめ#

見た目が少々いびつですが、次でオブジェクトから希望するキーのユニオン型を生成できます。

typescript
type Language = keyof typeof conf;
typescript
type Language = keyof typeof conf;

疑問: keyof conf じゃダメなんですか?#

動作しません。なぜなら keyof は値ではなく (オブジェクトの) 型に対して使用できるからです。一方 typeof は値から型を生成するのでこの順番で使用する必要があります。