Pick 是 TypeScript 中用于静态精简对象属性的工具类型,通过指定键名联合类型在编译期生成安全子集类型,保留原属性的可选性与只读性,不支持嵌套属性提取。

Pick 是 TypeScript 中最直接、最可控的属性精简工具。它不靠猜测、不靠运行时过滤,而是在类型层面静态地“按名取值”,只要属性名明确且存在,就能安全生成新类型。
核心用法:指定键名,生成子集类型
Pick'name' | 'id')。K 必须是 T 所有键名的子集,否则编译报错——这正是“精准”的保障。
- 接口或类型定义必须已存在(比如
interface User { id: number; name: string; email: string; createdAt: Date; }) - 使用
Pick<User, 'id' | 'name'>得到{ id: number; name: string; } - 若误写
Pick<User, 'username'>,TS 立即提示Type '"username"' does not satisfy the constraint 'keyof User'
应对庞大对象的实用技巧
面对几十个字段的复杂类型(如后端返回的完整用户模型),手动列键名易出错。可结合 keyof 和联合类型提升可维护性:
- 用
keyof User自动获取所有可用键,避免拼写错误 - 定义常量联合类型:
type PublicKeys = 'id' | 'name' | 'avatar' | 'bio';,再写Pick<User, PublicKeys> - 组合其他工具类型:比如先
Omit<User, 'passwordHash' | 'sessionToken'>去掉敏感字段,再用Pick进一步聚焦
常见误区与避坑点
Pick 的“精准”依赖严格的类型约束,几个典型问题要注意:
-
键名必须字面量匹配:
Pick<User, keyof User>是合法的,但Pick<User, string>不行——因为string范围太大,无法保证是真实存在的键 -
不处理嵌套属性:Pick 只作用于第一层。想提取
address.city,需先用Pick<User, 'address'>,再单独处理address类型 -
保留原属性的可选性与只读性:如果
email?: string,那么Pick<User, 'email'>中的email仍是可选;readonly id: number也会被保留为只读
真实场景示例:API 响应瘦身
假设后端返回一个含 28 个字段的 FullProduct 类型,前端列表页只需展示 ID、标题、价格和主图:
type ListProduct = Pick<FullProduct, 'id' | 'title' | 'price' | 'coverImageUrl'>;
// 编译期即确保这四个字段一定存在,且类型完全对齐
const renderItem = (item: ListProduct) => <div>{item.title} — ¥{item.price}</div>;
后续如果后端修改了字段名,或前端误用了不存在的键,TS 都会在保存时立刻报错,无需等运行时才发现。


















