(拼多多考题)TypeScript 工具类型:Pick、Omit、Partial、Required

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

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

例如用户模型:

ts 复制代码
interface User {
    id: number;
    name: string;
    age: number;
    email: string;
    password: string;
}

完整的 User 包含:

sql 复制代码
User
 |
 |-- id
 |-- name
 |-- age
 |-- email
 |-- password

但是实际开发中:

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

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

typescript 复制代码
interface UserCard {
    id:number;
    name:string;
}

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

会出现一个问题:

如果 User 修改了字段:

rust 复制代码
name -> username

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

大型项目中,这会导致:

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

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


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

什么是 Pick?

Pick 的作用:

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

语法:

swift 复制代码
Pick<类型, 字段>

例如:

ini 复制代码
type UserPreview = Pick<User, 'id' | 'name'>;

表示:

从 User 中选择:

  • id
  • name

生成:

ini 复制代码
type UserPreview = {
    id:number;
    name:string;
}

等价于:

typescript 复制代码
interface UserPreview {
    id:number;
    name:string;
}

使用:

css 复制代码
const user: UserPreview = {
    id:1,
    name:"张三"
}

正确。

但是:

css 复制代码
const user: UserPreview = {
    id:1,
    name:"张三",
    age:18
}

会报错。

因为:

复制代码
UserPreview 不包含 age

Pick 的实际应用

例如用户卡片:

页面只需要:

复制代码
用户名
头像

那么:

ini 复制代码
type UserCard = Pick<User, 'name' | 'avatar'>

不用重新定义接口。


2. Omit:排除字段

什么是 Omit?

Omit 和 Pick 相反:

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

语法:

sql 复制代码
Omit<类型, 字段>

例如:

ini 复制代码
type UserWithoutPassword = Omit<User,'password'>

表示:

保留 User 的所有字段:

但是删除:

复制代码
password

结果:

css 复制代码
{
    id:number;
    name:string;
    age:number;
    email:string;
}

实际应用:隐藏敏感数据

数据库中的用户:

typescript 复制代码
interface User {
    id:number;
    name:string;
    password:string;
}

但是返回给前端:

不能包含:

复制代码
password

所以:

ini 复制代码
type UserResponse = Omit<User,'password'>

避免密码泄露。


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

什么是 Partial?

Partial 的作用:

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


例如:

typescript 复制代码
interface User {
    id:number;
    name:string;
    email:string;
}

正常情况下:

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

所有字段必须存在。

但是修改用户资料时:

用户可能只修改名字:

json 复制代码
{
    "name":"李四"
}

这时候:

ini 复制代码
type UpdateUser = Partial<User>

得到:

css 复制代码
{
    id?:number;
    name?:string;
    email?:string;
}

? 表示:

这个字段可以不存在。

所以:

css 复制代码
const update:UpdateUser = {
    name:"李四"
}

合法。


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

Required 和 Partial 相反。

作用:

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

例如:

csharp 复制代码
interface Config {
    theme?:string;
    language?:string;
}

原本:

arduino 复制代码
const config = {
    theme:"dark"
}

合法。


使用:

ini 复制代码
type CompleteConfig = Required<Config>

变成:

c 复制代码
{
    theme:string;
    language:string;
}

现在:

arduino 复制代码
const config:CompleteConfig = {
    theme:"dark"
}

错误。

因为:

缺少 language。


四个工具类型对比

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

工程中的核心思想

不要:

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

而应该:

sql 复制代码
        User
         |
 ----------------
 |      |        |
Pick  Omit   Partial
 |      |        |
页面   API     表单

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


总结

TypeScript 工具类型解决的是:

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

其中:

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

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

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

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

相关推荐
miofly1 小时前
GitHub 今日推荐|rea:用 MCP 把反编译器和 AI agent 接到一起的逆向工具
typescript·开源·github
ZoeLandia11 小时前
React11:数据请求与 TanStack Query
前端·react.js·typescript·react
康小旺1 天前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
vue.js·typescript
ZoeLandia1 天前
React08:自定义 Hook
开发语言·前端·react.js·typescript
aloha_7892 天前
HTML、JavaScript 与 TypeScript 基础速查
javascript·typescript·html
离歌漠3 天前
《我用 Tauri 做了一个本地开发工具箱》
rust·typescript·vue
enjoy编程3 天前
playwright学习-I
typescript·vue·nodejs·1024程序员节·playwright
iDao技术魔方3 天前
Bun v1.4.4 实战:用 bun fmt 替掉 prettier 的 5 个步骤
typescript·1024程序员节
梅雅达编程笔记3 天前
Day 17 | uni-app 小程序:前端从零搭建
微信小程序·typescript·uni-app·vue3·pinia·前端开发·全栈
康小旺4 天前
TypeScript 编译器开始卷 Rust 了:Cloudflare 的 tsrs 到底想干嘛?
rust·typescript