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に合わせて値を抽出をしている
ということになりました。
コメント