技術とかの雑なToday I Learnedメモ

keyof typeofの使いどころ

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.jsoncompilerOptionskeyofStringsOnly: 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だとオペランドを指定しなければいけないので、オペランドがプロパティ不定のオブジェクトだと真価を発揮しそう。