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

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

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

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

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

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

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

typeof

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

📄️ オブジェクトから型を生成する

多くの言語では型による構造体、オブジェクトの定義をしてからコーディングが始まりますが、元がJavaScriptであるTypeScriptにはそのような決まりがないことも多々あります。

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

ts
type TypeOfLanguage = typeof conf;
type TypeOfLanguage = { en: string; fr: string; es: string; ja: string; zh: string; }
ts
type TypeOfLanguage = typeof conf;
type TypeOfLanguage = { en: string; fr: string; es: string; ja: string; zh: string; }

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

keyof

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

ts
type Language = keyof TypeOfLanguage;
type Language = "en" | "fr" | "es" | "ja" | "zh"
ts
type Language = keyof TypeOfLanguage;
type Language = "en" | "fr" | "es" | "ja" | "zh"

となります。

📄️ keyof型演算子

keyofはオブジェクト型からプロパティ名を型として返す型演算子です。たとえば、nameプロパティを持つ型に対して、keyofを使うと文字列リテラル型の"name"が得られます。

まとめ

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

ts
type Language = keyof typeof conf;
type Language = "en" | "fr" | "es" | "ja" | "zh"
ts
type Language = keyof typeof conf;
type Language = "en" | "fr" | "es" | "ja" | "zh"

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

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

  • 質問する ─ 読んでも分からなかったこと、TypeScriptで分からないこと、お気軽にGitHubまで🙂
  • 問題を報告する ─ 文章やサンプルコードなどの誤植はお知らせください。