オブジェクトからキーの型を生成する
オブジェクトからキーだけ欲しい
あるメッセージが言語ごとに定義されているとします。
tsconstconf = {en : "Are you sure?",fr : "Êtes-vous sûr?",es : "Está seguro?",ja : "よろしいですか?",zh : "您确定吗?",};
tsconstconf = {en : "Are you sure?",fr : "Êtes-vous sûr?",es : "Está seguro?",ja : "よろしいですか?",zh : "您确定吗?",};
内容は確認を促す変哲もないシステムのメッセージです。このオブジェクトを使ってシステムがサポートしている言語の一覧を作ります。次のようなユニオン型が今回の目的です。
tstypeLanguage = "en" | "fr" | "es" | "ja" | "zh";
tstypeLanguage = "en" | "fr" | "es" | "ja" | "zh";
typeof
頻出するこのtypeofはJavaScriptのものではなく、TypeScriptのtypeofです。これをオブジェクトに対して使用している例は前のページにあるとおりです。
📄️ オブジェクトから型を生成する
多くの言語では型による構造体、オブジェクトの定義をしてからコーディングが始まりますが、元がJavaScriptであるTypeScriptにはそのような決まりがないことも多々あります。
この例で実行すれば次のような型TypeOfLanguageが生成されるでしょう (型名は便宜的なものです) 。
tstypeTypeOfLanguage = typeofconf ;
tstypeTypeOfLanguage = typeofconf ;
ここまでくればあとは少しです。TypeOfLanguage型のキーだけを型にしてしまいます。
keyof
keyofはオブジェクトの型に使うとそのオブジェクトのキーをユニオン型にして返します。上記のTypeOfLanguage型があれば
tstypeLanguage = keyofTypeOfLanguage ;
tstypeLanguage = keyofTypeOfLanguage ;
となります。
📄️ keyof型演算子
keyofはオブジェクトの型からプロパティ名を型として返す型演算子です。たとえば、nameプロパティを持つ型に対して、keyofを使うと文字列リテラル型の"name"が得られます。
まとめ
見た目が少々いびつですが、次でオブジェクトから希望するキーのユニオン型を生成できます。
tstypeLanguage = keyof typeofconf ;
tstypeLanguage = keyof typeofconf ;
疑問: keyof confじゃダメなんですか?
動作しません。なぜならkeyofは値ではなく (オブジェクトの) 型に対して使用できるからです。一方typeofは値から型を生成するのでこの順番で使用する必要があります。