TypeScript 中,Pick 和 Omit 是两个非常常用且强大的内置工具类型(Utility Types)

TypeScript中的Pick和Omit是两个常用工具类型,用于从现有类型中选取或排除属性。


Pick通过"白名单"机制选取指定属性(如从User类型中只选id和name),适用于提取少量字段的场景。


Omit则通过"黑名单"机制排除指定属性(如从User中剔除id和createdAt),适用于复用大部分字段的情况。


两者配合能有效减少重复类型定义,保持代码DRY原则,常见于API响应分层、表单验证等场景,通过类型运算实现数据的精确控制。


在 TypeScript 中,Pick 和 Omit 是两个非常常用且强大的内置工具类型(Utility Types)。


它们都基于泛型实现,主要用于对现有的对象类型进行"重塑",即从一个复杂的类型中选取部分属性或剔除部分属性,从而生成新的类型。


这两个工具类型在处理 API 响应、表单数据、数据库模型映射等场景中极其高频。


1. Pick<Type, Keys>


定义 :
Pick 用于从类型 Type 中选取 一组特定的属性键 Keys,并构造一个新的类型。新类型只包含你指定的那些属性。


语法:

TypeScript 复制代码
type Pick<Type, Keys extends keyof Type> = {
  [Property in Keys]: Type[Property];
};

通俗理解 :

"我只想要这个大对象里的这几样东西。"

代码示例 :

假设我们有一个描述用户的完整类型 User:

TypeScript 复制代码
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
  role: 'admin' | 'guest';
  createdAt: Date;
}

如果我们只想在用户列表页面显示 id 和 name,不想暴露敏感信息(如 email)或不必要的元数据(如 createdAt),可以使用 Pick:

TypeScript 复制代码
// 只保留 id 和 name
type UserListItem = Pick<User, 'id' | 'name'>;

// UserListItem 等价于:
// {
//   id: number;
//   name: string;
// }

const userItem: UserListItem = {
  id: 1,
  name: "Alice",
  // error: 如果这里加上 email 或其他属性,TS 会报错
};

2. Omit<Type, Keys>


定义 :
Omit 用于从类型 Type 中剔除 (省略)一组特定的属性键 Keys,并构造一个新的类型。新类型包含原类型中除了指定键以外的所有属性。


语法:

TypeScript 复制代码
type Omit<Type, Keys extends keyof any> = Pick<Type, Exclude<keyof Type, Keys>>;

(注:它的内部实现其实就是先算出"剩下的键",然后再用 Pick 选出来)

通俗理解 :

"我想要这个大对象里的所有东西,除了这几样。"

代码示例 :

继续使用上面的 User 类型。如果在创建新用户时,id 和 createdAt 是由数据库自动生成的,前端不应该传递这两个字段,我们可以使用 Omit:

TypeScript 复制代码
// 剔除 id 和 createdAt
type CreateUserInput = Omit<User, 'id' | 'createdAt'>;

// CreateUserInput 等价于:
// {
//   name: string;
//   email: string;
//   age: number;
//   role: 'admin' | 'guest';
// }

const newUser: CreateUserInput = {
  name: "Bob",
  email: "bob@example.com",
  age: 25,
  role: "guest",
  // error: 如果这里加上 id 或 createdAt,TS 会报错
};

3. 核心对比总结

特性 Pick Omit
操作逻辑 白名单机制:只保留列出的属性 黑名单机制:删除列出的属性,保留其余
适用场景 当你需要提取少量字段组成新视图时 当你需要复用大部分字段,仅排除少数几个字段时
数学逻辑 交集 (Intersection) 概念 差集 (Difference) 概念
内部关系 基础构建块 通常由 Pick + Exclude 组合实现

4. 实际开发中的高频用法

场景 A:API 响应分层

后端返回完整的用户信息,但前端不同组件需要不同的数据结构。

TypeScript 复制代码
// 完整数据
type ApiUserResponse = User;

// 公开个人资料页(隐藏 email 和 role)
type PublicProfile = Omit<User, 'email' | 'role'>;

// 管理员表格(只需要关键标识)
type AdminTableItem = Pick<User, 'id' | 'name' | 'role'>;

场景 B:表单验证

实体类包含数据库字段,但表单输入不需要某些自动生成的字段。

TypeScript 复制代码
// 数据库实体
interface Product {
  id: string;
  sku: string;
  price: number;
  stockCount: number;
  lastUpdated: string; 
}

// 创建产品表单(不需要 id 和 lastUpdated)
type CreateProductForm = Omit<Product, 'id' | 'lastUpdated'>;

// 更新产品表单(可能只需要部分字段可选)
type UpdateProductForm = Partial<Pick<Product, 'price' | 'stockCount'>>;

总结

  • Pick = 做减法(从全集里挑出子集)。
  • Omit = 做排除(从全集里去掉子集)。

掌握这两个工具类型,可以极大地减少重复定义接口的代码量,并保持类型定义与源数据模型的一致性(DRY 原则)。

相关推荐
FYKJ_201031 分钟前
springboot刑事案件管理系统03047-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
用户0934077735145 小时前
HarmonyOS WPS Open SDK 实践:从 HAR 集成到 OpenFileRequest 最小闭环
typescript·harmonyos
FYKJ_20105 小时前
springboot雅集社区养老管理系统04456-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
FYKJ_20105 小时前
express皖美特色农产品网售系统53118-计算机课程设计、毕业设计
javascript·vue.js·spring boot·mysql·typescript·spark·express
FYKJ_20105 小时前
springboot羽毛球场地管理系统00626-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
FYKJ_20106 小时前
django药饮个性化推荐系统54839-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
濮水大叔11 小时前
Cabloy全栈框架的两个SSR入口:Vona集成式SSR vs Zova独立式SSR
typescript·node.js·全栈
nyaomaru12 小时前
你的 Type Guard 可能会悄悄地与 TypeScript 类型发生偏移 🔧
后端·typescript
右耳朵猫AI8 天前
Web前端周刊2026W38 | React 19.3 发布、StyleX 深潜、jsdom 30.1 提速
前端·javascript·react.js·typescript·node.js
溪语流沙8 天前
Django + Vue电商项目第001讲:开篇|注册登录加增删改查,那不是电商
redis·python·mysql·docker·typescript·django·vue