一文掌握 TypeScript 工具类型:Record、Partial、Omit、Pick 等实战用法

一文搞懂 TypeScript 常用泛型工具类型(Record、Partial、Omit、Pick 等)

TypeScript 内置了一批 泛型工具类型 ,比如 RecordPartialOmitPick 等,它们能基于已有类型快速生成新类型,避免重复定义,让类型既安全又灵活。

如果你停留在只会"用",却不太理解 为什么会出现原理是什么最佳实践如何选型 。本文就带你从 痛点 → 工具类型 → 实战 → 原理,一次性搞透。

1. 为什么会出现?

早期 TypeScript 开发的痛点:

  • 相似的类型要重复写多份
  • 为了适配不同场景,需要频繁复制粘贴类型定义
  • 一旦源类型变动,所有相关类型都要手动更新

泛型工具类型就是为了解决这些问题:

  • 减少重复:用组合和派生代替重复声明
  • 提升安全:编译器帮你检查类型错误
  • 更灵活:业务变动时派生类型自动适配

2. 常用工具类型列表

工具类型 作用 简述原理
Record<K, T> 将键集合 K 映射到类型 T 映射类型批量生成属性
Partial<T> 将所有属性设为可选 ? 修饰符映射
Omit<T, K> T 排除 K 属性 Pick + Exclude
Pick<T, K> 只保留 K 指定属性 映射类型选择
Required<T> 将所有属性设为必填 去掉 ? 修饰符
Readonly<T> 将所有属性设为只读 readonly 修饰符映射
Exclude<T, U> 从联合类型 T 排除类型 U 条件类型
Extract<T, U> 从联合类型 T 提取 U 类型 条件类型
NonNullable<T> 排除 nullundefined 条件类型
ReturnType<F> 获取函数返回值类型 infer 推导
InstanceType<C> 获取构造函数实例类型 infer 推导

3. 使用场景与原理

3.1 Record:权限表

ts 复制代码
type Role = 'admin' | 'editor' | 'viewer';
type Permission = 'read' | 'write' | 'delete';

const rolePermissions: Record<Role, Permission[]> = {
  admin: ['read', 'write', 'delete'],
  editor: ['read', 'write'],
  viewer: ['read']
};

原理Record<K, T> 本质就是"用 K 的所有键生成一组属性":

ts 复制代码
type Record<K extends keyof any, T> = {
  [P in K]: T;
}

3.2 Partial:更新用户信息

ts 复制代码
interface UserProfile {
  id: number;
  name: string;
  email: string;
}
function updateUser(id: number, updates: Partial<UserProfile>) {
  // ...
}

updateUser(1, { email: 'new@example.com' });

原理 :通过映射类型给所有属性加上 ?

ts 复制代码
type Partial<T> = {
  [P in keyof T]?: T[P];
}

3.3 Omit:去除敏感字段

ts 复制代码
interface User {
  id: number;
  name: string;
  password: string
}
type SafeUser = Omit<User, 'password'>;

原理 :其实就是 Pick + Exclude 的组合:

ts 复制代码
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>

3.4 Pick:只要部分字段

ts 复制代码
type UserNameEmail = Pick<UserProfile, 'name' | 'email'>;

原理 :只保留 K 中的键:

ts 复制代码
type Pick<T, K extends keyof any> = {
  [P in K]: T[P]
}

3.5 Required:接口必填化

ts 复制代码
type StrictUser = Required<Partial<UserProfile>>;

3.6 Readonly:让属性只读

ts 复制代码
const config: Readonly<{ apiUrl: string }> = {
  apiUrl: 'https://api.example.com'
};
config.apiUrl = '' // 报错

3.7 Exclude & Extract:联合类型过滤

ts 复制代码
type T = 'a' | 'b' | 'c';

type WithoutB = Exclude<T, 'b'>; // 'a' | 'c'
type OnlyB = Extract<T, 'b'>; // 'b'

对比:

  • Pick/Omit 好比一个 对象裁剪器 :我有一张"用户表单",我要么只留下 name/email(Pick),要么去掉 password(Omit)。
  • Exclude/Extract 好比一个 集合过滤器 :我有一个集合 {'a','b','c'},我去掉 b(Exclude)或只要 b(Extract)。

3.8 NonNullable:去掉 null/undefined

ts 复制代码
type Value = string | null | undefined;
type SafeValue = NonNullable<Value>; // string

3.9 ReturnType & InstanceType:类型推导

ts 复制代码
function getUser() {
  return { id: 1, name: 'Alice' };
}
type UserReturn = ReturnType<typeof getUser>; 
// { id: number; name: string; }

class Person { name = 'Bob'; }
type PersonInstance = InstanceType<typeof Person>; 
// Person

4. 工具类型的实现思路

常见实现方式有三类:

  1. 映射类型Record / Partial / Pick / Omit / Readonly / Required

  2. 条件类型Exclude / Extract / NonNullable

  3. infer 推导ReturnType / InstanceType

5. 最佳实践与注意事项

  • 避免过度嵌套Partial<Required<Pick<...>>> 会让类型难以阅读,尽量保持扁平。
  • 业务分层使用 :比如 DTO 层用 Omit 去掉数据库 ID,前端表单用 Partial 允许字段可选。
  • 结合自定义类型:内置工具类型不够时,可以通过条件类型 + 映射类型组合,写出自己的工具类型。

参考更多资料:

相关推荐
Jerry说前后端4 分钟前
Android 移动端 UI 设计:前端常用设计原则总结
android·前端·ui
熊猫钓鱼11 分钟前
基于Trae CN与TrendsHub快速实现的热点百事通
前端·trae
LIUENG18 分钟前
Vue3 响应式原理
前端·vue.js
讨厌吃蛋黄酥21 分钟前
前端居中九种方式血泪史:面试官最爱问的送命题,我一次性整明白!
前端·css
龙在天25 分钟前
🤩 用Babel自动埋点,原来这么简单!
前端
Hierifer25 分钟前
跨端实现之网络库拦截
前端
随笔记27 分钟前
react-router里的两种路由方式有什么不同
前端·react.js
前端李二牛27 分钟前
异步任务并发控制
前端·javascript
imLix1 小时前
RunLoop 实现原理
前端·ios
wayman_he_何大民1 小时前
初始机器学习算法 - 关联分析
前端·人工智能