实现 Pick Pick
实现 Pick Pick
Challenge / 题目
Implement the built-in Pick<T, K> without using it.
不使用内置工具类型 Pick<T, K>,自己实现一个 MyPick<T, K>。
For example:
例如:
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
// { title: string; completed: boolean }Solution / 解答
type MyPick<T, K extends keyof T> = {
[P in K]: T[P]
}The core idea is simple: K is the subset of keys we want, and mapped types let us build a new object type by iterating over those keys.
核心思路很直接:K 就是我们要保留的属性集合,而映射类型可以让我们遍历这些属性并重新构造一个对象类型。
Step by step / 逐步拆解
1. Restrict K to keys from T
1. 约束 K 必须来自 T 的键
K extends keyof TThis prevents invalid keys such as MyPick<Todo, 'foo'>.
这样可以阻止非法属性名,比如 MyPick<Todo, 'foo'>。
2. Iterate over K
2. 遍历 K
[P in K]This means: for every key P inside K, create one property in the new type.
它的意思是:对于 K 中的每一个属性名 P,都在新类型里生成一个同名属性。
3. Reuse the original property type
3. 复用原对象上的属性类型
T[P]This is an indexed access type. It reads the value type of property P from T.
这里用的是索引访问类型,它会从 T 上取出属性 P 对应的值类型。
Putting everything together:
合起来就是:
type MyPick<T, K extends keyof T> = {
[P in K]: T[P]
}Walkthrough / 推导过程
interface Todo {
title: string
description: string
completed: boolean
}
type Result = MyPick<Todo, 'title' | 'completed'>K is 'title' | 'completed', so the mapped type only iterates over these two keys:
这里 K 是 'title' | 'completed',所以映射类型只会遍历这两个属性:
type Result = {
title: Todo['title']
completed: Todo['completed']
}After substitution:
展开后得到:
type Result = {
title: string
completed: boolean
}Why this works / 为什么这样可行
Pick is essentially a filtered object reconstruction. Unlike Omit, it does not need key remapping or never. We already know exactly which keys to keep, so we just iterate over them.
Pick 本质上就是一次“按指定键重建对象”。它不像 Omit 那样需要通过 never 过滤属性,因为这里要保留哪些键已经明确写在 K 里了,直接遍历即可。
Key Takeaways / 核心要点
keyof Tgets all valid property names fromT.K extends keyof Tensures the selected keys are legal.[P in K]: T[P]is the standard mapped-type pattern for rebuilding object types.Pickis one of the simplest and most important examples of mapped types.keyof T用来获取T的全部合法属性名。K extends keyof T用来限制选择范围,避免无效键。[P in K]: T[P]是映射类型最经典的重建对象写法。Pick是理解映射类型最基础、也最重要的例子之一。
