实现 Pick
题目
实现 TS 内置的 Pick<T, K>
,但不可以使用它。
从类型 T
中选择出属性 K
,构造成一个新的类型。
例如:
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
}
题目来源:https://tsch.js.org/4/zh-CN
解答
type MyPick<T, K extends keyof T = keyof T> = {
[P in K]: T[P]
}
思路
keyof
取出key
MyPick<Todo, 'title' | 'completed'>
尖括号的右侧是'title' | 'completed'
,它们是Todo
类型的两个key。
所以,需要用keyof T
取出。
keyof T
等于 'title' | 'completed' | 'description'
。
extends
对泛型进行约束
'title' | 'completed'
是 'title' | 'completed' | 'description'
的子集(keyof T
)。
所以 'title' | 'completed'
等于 K extends keyof T
。
in
遍历枚举类型
[P in K]
的意思是将K
中的key
遍历出来,赋予P
。
T[P]
的意思是将T
中对应的key
=== P
的值取出来。
所以,[P in K]: T[P]
的含义就很明白了。
为什么要加 = keyof T
?
如果以MyPick<T>
中形式调用时,T
如果没有默认值,会报错。
所以,需要加上 = keyof T
。