[TypeScript]Pickについて、実際に実装して理解する。

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 T

keyofってなんだ?
こういうときは具体例で見ていこう

以下の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に合わせて値を抽出をしている

ということになりました。

コメント