keyof typeof の使いどころ
文字列が Object 型の key に存在してるか確認したい
この記事を読んでいて、これはたぶん keyof でできるんじゃないかな?と思って調べていた。
TypeScript のルックアップ型と keyof キーワード - 30 歳からのプログラミング
ルックアップ型
keyof を調べていたけどルックアップ型というやつが出てきて、「なんとなくあるのは知っていたけど名称を知らなかった」ものがひとつ解決されたので個人的に嬉しかった。
ルックアップ型は
type Test = {
hoge: string
fuga: number
}
みたいな型があったときに
type LookupTest = Test['hoge'] // type LookupTest = string
という感じで型['プロパティ']
というオブジェクトのプロパティへのアクセスのような形で型を定義できる。
これをルックアップ型というのだから、オブジェクトのプロパティにこの形でアクセスすることを「ルックアップ」と言ったりするのかな?
ちなみに配列の要素の型は
type ArrayTest = string[]
type ArrayLookupTest = ArrayTest[number] // type ArrayLookupTest = string
のように取れるらしい。すごい。
keyof
本題に戻って、keyof はオブジェクトのキーの一覧を string の Union 型として取り出すやつのことで、これ自体は知っていた。
type TestObject = {
hoge: string
fuga: number
}
type TestKeyofType = keyof TestObject // type TestKeyofType = 'hoge' | 'fuga'
これをルックアップ型と組み合わせることで、「オブジェクトのキーの型の一覧」を取り出せる。
type TestObject = {
hoge: string
fuga: number
}
type TestKeyofLookupType = TestObject[keyof TestObject] // type TestKeyofLookupType = string | number
keyofStringsOnly
keyof T
はどうやらstring | number | symbol
のサブタイプらしい。
なので、オブジェクトのキーに string だけでなく number や symbol を使っている場合はそのまま型を取得できるとのこと(でないとルックアップ型と組み合わせたときにstring | number
みたいにならないのでたしかに)
keyof T
で string 以外のキーを無視したい場合はtsconfig.json
のcompilerOptions
でkeyofStringsOnly: true
にするといいらしい。
こうすると、number や symbol は string に変換されるのではなく無視されるとのこと。
keyof typeof
TypeScript の『typeof X[keyof typeof X]』の意味を順を追って理解する | Enjoy IT Life
他の記事も見てたらkeyof typeof
を使う方法も書いてあった。
typeof T は T の型を文字列として返すので、keyof typeof T
とすることで T のプロパティの一覧を文字列で取得できる。
type KeyofTypeofTestObject = {
hoge: string
fuga: number
1234: string
}
type KeyofTypeofTestType = keyof typeof KeyofTypeofTestObject // type KeyofTypeofTestType = 'hoge' | 'fuga' | '1234' が取れてほしかった
と思ったのだけど、TS Playground で確認してみたらどうやら ↑ の1234
は number 型でそのまま取ってきていたので、普通に keyof を使った場合と変わらないかも?
keyof T
は型を指定しなければいけないけど、keyof typeof hoge
だとオペランドを指定しなければいけないので、オペランドがプロパティ不定のオブジェクトだと真価を発揮しそう。