TypeScriptでオブジェクトにある値だけを許容する型を作成する記事を読んだ
TypeScriptでオブジェクトにある値だけを許容する型を作成する
読んだのでメモ。
keyof typeof のこと昔学んだな〜と思ってたけど、嬉しいポイントとか書いてある記事まで読んだ記憶がない(あったとしても抜け落ちている)ので、改めて知っておこうと思い読んだ。
前に書いたのは2021/11/06のやつとか。
as const をつける
- 記事の例だと as const をつけないとプロパティがすべて number 型で推論される
- as const をつけることで1型や2型のような[数値]型として認識される
- number 型で推論されるのは、他の number の値も入る可能性があると考慮されるからで、これを Widening と呼ぶ
- as const をつけると readonly プロパティが付与されるので代入しようとするとエラーが出る
keyof
- Object のプロパティ名が Union Types で取得できる
type A = { a: 1; b: 2 }
だったら、keyof A // => 'a' | 'b'
のようになる
typeof
- 値から型を取得する
- これはよく見るのでまあいいかな
- typeof で変な挙動をする document.all の記事が今日流れてきたのでこれも読む
keyof typeof
- keyof typeof Obj でそのオブジェクトのプロパティ名の Union Types を取得して
- それを使って Obj のプロパティの型に↑を指定すれば、プロパティの値の Union Types になる
- 具体例は記事が分かりやすいが↓に書いておくと
type Hoge = {
a: 1
b: 2
c: 'hoge'
}
// keyof typeof Hoge => 'a' | 'b' | 'c'
// typeof Hoge['a' | 'b' | 'c']
type Values = typeof Hoge[keyof typeof Hoge] // => 1 | 2 | 'hoge'
そういえば
- 値から型を得るのってアレだったような……
- 7/28のやつ
- odan さんにリプライをもらったので、値から型を得るのはどういう場合なら許容されるのかを考えてみる
なるほど
— odan (@odan3240) August 1, 2022
これは状況によるかなあって思いました(記事の例は抽象的なので判断についてなんとも言えない
それから berlysia さんもこのやり取りを見ててくれたのかツイートしてくれたので貼る
型から値作らなきゃいけないのはReducerのinitialStateみたいなやつ。値から型作って良いのは定数みたいなやつ。
— berlysia💭 (@berlysia) August 1, 2022
有識者のツイート、助かります。
話を戻して、
keyof typeof の嬉しいポイント
- 上書きできない
- as const の影響?影響って言うとアレだけど良い意味での影響
- 型定義を変更する必要がない
- 上述の値から型を作る話の部分
- たしかにこれは便利だと思う
keyof typeof を使わないと
- 変更の度に足す部分が増える
- switch 文の分岐とか他の場所で変更する箇所が増えてバグりやすくなる
switch 文の defalut
- never にしとくとバグらないよ!
- これは昔どこかで見たので覚えてるんだけど、そもそも switch 文を最近あまり書いてない