Skip to main content

实现 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