TypeScriptの既存の型から任意の項目だけを抽出して新たな型にするPickというものがある。
今回はこれを自力で実装して理解する
目標は以下のMyPickを実装すること。
interface Todo {  title: string  description: string  completed: boolean}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {  title: 'Clean room',  completed: false,}なお、この例はtype-challengesから持ってきている。
https://github.com/type-challenges/type-challenges/blob/master/questions/4-easy-pick/README.ja.md
回答例はわずかこれだけ
type MyPick<T, K extends keyof T> = { [S in K]: T[S] }うん、全くわからん。
ジェネリクスっぽいことをしているのは分かるが。。。
少しずつ紐解いて行こう。
まずは、これ
K extends keyof Tkeyofってなんだ?
こういうときは具体例で見ていこう
以下のUser型があるとする
type User = {  id: number  name: String}ここでUser型に対して、keyofしてみる
type UserKeys = keyof User // "id" | "name"なるほど。
どうやらkeyofはオブジェクトのkeyの一覧を取得して、orですべて取得するらしい。
次はこれ
[S in K]: T[S]まずは
;[S in K]これは以下の通り書き換えられる
[S in keyof T]keyofと組み合わせることにより、上記のUserの例で行くと
;['id' | 'name']となる。
また
T[S]は、User型の例で行くと
User[S]となるので、User型の対応するキーの値ということになる。
まとめ
すなわち、
type MyPick<T, K extends keyof T> = { [S in K]: T[S] }は、T型のオブジェクトに対して、T型のkeyに存在するkeyに合わせて値を抽出をしている
ということになりました。