TypeScripy , Pick, Omit, Partial 如何使用

作者:Administrator 发布时间: 2025-12-16 阅读量:8 评论数:0

这也是 TypeScript 中最高频使用的“三剑客”。

它们的本质都是**“基于现有的类型,生成一个新的类型”**。这样你就不用把相似的类型定义写好几遍(DRY 原则)。

为了演示,我们先定义一个基础类型 User(用户):

TypeScript

interface User {
  id: number;
  name: string;
  email: string;
  age: number;
  isAdmin: boolean;
}

1. Partial<T> (全部变为可选)

作用: 把一个类型的所有属性都变成 可选的 (?)

场景: 最常见于 “更新数据” 的接口。

比如你只想修改用户的 name,不想传 id 或 email,这时候如果直接用 User 类型就会报错,因为缺属性。

TypeScript

// ❌ 错误做法:直接用 User,必须传所有属性
const updateData: User = { name: "Gemini" }; // 报错:缺少 id, email...

// ✅ 正确做法:使用 Partial
// 等价于:{ id?: number; name?: string; ... }
type UpdateUserDto = Partial<User>;

const updateData: UpdateUserDto = {
  name: "Gemini" // 没问题,其他属性不传也可以
};

2. Pick<T, Keys> (只选你要的)

作用: 从一个大类型中,挑选出几个你需要的属性,组成新类型。

场景: “UI 组件传参” 或 “数据预览”。

比如在用户列表页,你只需要展示 name 和 email,不需要把敏感的 isAdmin 或无用的 age 传给组件。

TypeScript

// ✅ 使用 Pick 挑选 name 和 email
// 等价于:{ name: string; email: string; }
type UserPreview = Pick<User, "name" | "email">;

const userCard: UserPreview = {
  name: "Gemini",
  email: "[email protected]",
  // id: 1,      // ❌ 报错:UserPreview 里没有 id
  // age: 18     // ❌ 报错
};

3. Omit<T, Keys> (排除你不要的)

作用: 从一个大类型中,剔除掉几个你不需要的属性,剩下的组成新类型。它是 Pick 的反义词。

场景: “创建数据”。

比如创建一个新用户时,id 是数据库自动生成的,isAdmin 默认为 false,前端不需要传这两个字段。

TypeScript

// ✅ 使用 Omit 剔除 id 和 isAdmin
// 等价于:{ name: string; email: string; age: number; }
type CreateUserDto = Omit<User, "id" | "isAdmin">;

const newUser: CreateUserDto = {
  name: "Gemini",
  email: "[email protected]",
  age: 20
  // id: 1 // ❌ 报错:CreateUserDto 中不包含 id
};

4. 进阶:它们是怎么实现的? (原理篇)

理解原理能让你写出更牛的类型。它们底层主要依赖 映射类型 (Mapped Types)索引查询 (keyof)

Partial 的源码

原理:遍历 T 的所有 key,加上 ?

TypeScript

type Partial<T> = {
  [P in keyof T]?: T[P];
};

Pick 的源码

原理:遍历你指定的 K (Keys),去 T 里面拿对应的类型。

TypeScript

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

Omit 的源码 (稍微复杂)

原理:先算出 T 的所有 key 中 不包含 K 的部分(用 Exclude),然后再用 Pick 选出来。

TypeScript

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

5. 实战组合拳

在实际开发中,你经常需要组合使用它们。

场景: 更新用户信息时,id 是必须传的(为了知道更新谁),但其他信息是可选的。

TypeScript

// 1. 先用 Pick 选出 id (必填)
type IdPart = Pick<User, "id">;

// 2. 再用 Omit 把 id 排除,剩下的用 Partial 变可选
type RestPart = Partial<Omit<User, "id">>;

// 3. 用 & (交叉类型) 合并
type UpdateUserWithId = IdPart & RestPart;

// 结果:
// {
//   id: number;       // 必填
//   name?: string;    // 可选
//   email?: string;   // 可选
//   ...
// }

总结

  • Partial: 想偷懒,全变可选。

  • Pick: 做减法,只要这几个。

  • Omit: 做减法,不要这几个。

评论