TypeScript 工具类型:Pick、Omit、Partial、Required

18 阅读3分钟

在 TypeScript 项目中,我们经常会遇到一个问题:

一个对象有很多字段,但是不同业务场景需要的字段并不一样。

例如用户模型:

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

完整的 User 包含:

User
 |
 |-- id
 |-- name
 |-- age
 |-- email
 |-- password

但是实际开发中:

  • 用户列表只需要 id 和 name
  • 注册页面只需要 name 和 password
  • 用户详情不能返回 password
  • 修改用户时只修改部分字段

如果每个地方都重新定义接口:

interface UserCard {
    id:number;
    name:string;
}

interface UserDetail {
    id:number;
    name:string;
    email:string;
}

会出现一个问题:

如果 User 修改了字段:

name -> username

那么所有依赖 User 的接口都需要手动修改。

大型项目中,这会导致:

  • 类型重复
  • 字段不一致
  • 修改困难

所以 TypeScript 提供了工具类型(Utility Types),让我们可以基于已有类型生成新的类型。


1. Pick:从类型中挑选字段

什么是 Pick?

Pick 的作用:

从一个已有类型中选择指定字段,生成新的类型。

语法:

Pick<类型, 字段>

例如:

type UserPreview = Pick<User, 'id' | 'name'>;

表示:

User 中选择:

  • id
  • name

生成:

type UserPreview = {
    id:number;
    name:string;
}

等价于:

interface UserPreview {
    id:number;
    name:string;
}

使用:

const user: UserPreview = {
    id:1,
    name:"张三"
}

正确。

但是:

const user: UserPreview = {
    id:1,
    name:"张三",
    age:18
}

会报错。

因为:

UserPreview 不包含 age

Pick 的实际应用

例如用户卡片:

页面只需要:

用户名
头像

那么:

type UserCard = Pick<User, 'name' | 'avatar'>

不用重新定义接口。


2. Omit:排除字段

什么是 Omit?

Omit 和 Pick 相反:

从已有类型中删除指定字段。

语法:

Omit<类型, 字段>

例如:

type UserWithoutPassword = Omit<User,'password'>

表示:

保留 User 的所有字段:

但是删除:

password

结果:

{
    id:number;
    name:string;
    age:number;
    email:string;
}

实际应用:隐藏敏感数据

数据库中的用户:

interface User {
    id:number;
    name:string;
    password:string;
}

但是返回给前端:

不能包含:

password

所以:

type UserResponse = Omit<User,'password'>

避免密码泄露。


3. Partial:字段全部变成可选

什么是 Partial?

Partial 的作用:

将一个类型中的所有字段变成可选。


例如:

interface User {
    id:number;
    name:string;
    email:string;
}

正常情况下:

const user:User = {
    id:1,
    name:"张三",
    email:"xxx@qq.com"
}

所有字段必须存在。

但是修改用户资料时:

用户可能只修改名字:

{
    "name":"李四"
}

这时候:

type UpdateUser = Partial<User>

得到:

{
    id?:number;
    name?:string;
    email?:string;
}

? 表示:

这个字段可以不存在。

所以:

const update:UpdateUser = {
    name:"李四"
}

合法。


4. Required:字段全部变成必填

Required 和 Partial 相反。

作用:

将可选字段变成必填字段。

例如:

interface Config {
    theme?:string;
    language?:string;
}

原本:

const config = {
    theme:"dark"
}

合法。


使用:

type CompleteConfig = Required<Config>

变成:

{
    theme:string;
    language:string;
}

现在:

const config:CompleteConfig = {
    theme:"dark"
}

错误。

因为:

缺少 language。


四个工具类型对比

工具类型作用示例
Pick选择字段Pick<User,'id'>
Omit删除字段Omit<User,'password'>
Partial全部可选Partial<User>
Required全部必填Required<User>

工程中的核心思想

不要:

复制接口
复制字段
重复维护

而应该:

        User
         |
 ----------------
 |      |        |
Pick  Omit   Partial
 |      |        |
页面   API     表单

维护一个核心类型,然后根据业务需求组合新的类型。


总结

TypeScript 工具类型解决的是:

如何根据已有类型快速创建新的类型。

其中:

  • Pick:我要哪些字段
  • Omit:不要哪些字段
  • Partial:字段可以没有
  • Required:字段必须存在

在 React + TypeScript 项目中,这些工具类型大量用于:

  • API 数据类型定义
  • 表单类型定义
  • 页面展示类型定义
  • 数据传递类型约束

掌握这些工具类型,可以让大型项目中的类型维护更加稳定。