🐙
Type Challengeに入門する
最近ライブラリのラッパーを書くようになり、自分の型表現力の低さを痛感しているのでType Challengeに入門しようと思います。
存在自体は以前から知っていたのですが、めんどくさかったためやっていませんでした。今日から毎日最低1問取り組んでいきたいと思います。
初級・Pick
Pick<T, keys>を自作する問題です。まずPickについておさらいしておきます。
Pick<T, Keys>は、型TからKeysに指定したキーだけを含むオブジェクト型を返すユーティリティ型です。
具体例を見ていきましょう。
typeChallenge.ts
type Foo = {
foo1: string;
foo2: number;
foo3: string;
};
type Hoge = Pick<Foo, 'foo1' | 'foo2'>
// ↑は↓と同じ
type Bar = { foo1: string; foo2: number };
つまり型引数で取るべき値は①型Tと型Tのkeyの型ですね。
typeChallenge.ts
type MyPick<T, K extends keyof T> = {}
これで型引数の条件は満たせました。次に型を考えていきたいのですが、ここで詰まってしまいました。
typeChallenge.ts
type MyPick<T, Keys extends keyof T> = { [Key in Keys]: T[Keys] }
これで片方のエラーは消えたのですが、もう片方のエラーが消えません。回答を確認すると、
answer.ts
type MyPick<T, Keys extends keyof T> = { [Key in Keys]: T[Key] }
このようにしなければならなかったそうです。
T[Keys]にしてしまうと、KeysがUnion型の時にここもUnion型になってしまうんですね。今考えれば当然のことですが、やっている時は気づけませんでした。
感想
思ったより型戦闘力が低かったです。基本的なMapped Typeすら理解があやふやでした。毎日続けて少しでもマシな型戦闘力を身につけたいです。
Discussion