一文掌握 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 允许字段可选。
  • 结合自定义类型:内置工具类型不够时,可以通过条件类型 + 映射类型组合,写出自己的工具类型。

参考更多资料:

相关推荐
冰夏之夜影5 分钟前
【科普】Edge出问题后如何恢复出厂设置
前端·edge
葱头的故事1 小时前
vant van-uploader上传file文件;回显时使用imageId拼接路径
前端·1024程序员节
Mintopia1 小时前
🇨🇳 Next.js 在国内场景下的使用分析与实践指南
前端·后端·全栈
Mintopia2 小时前
深度伪造检测技术在 WebAIGC 场景中的应用现状
前端·javascript·aigc
BUG_Jia2 小时前
如何用 HTML 生成 PC 端软件
前端·javascript·html·桌面应用·1024程序员节
木易 士心2 小时前
CSS 样式用法大全
前端·css·1024程序员节
012925202 小时前
1.1 笔记 html 基础 初认识
前端·笔记·html
2501_929382652 小时前
[Switch大气层]纯净版+特斯拉版 20.5.0大气层1.9.5心悦整合包 固件 工具 插件 前端等资源合集
前端·游戏·switch·1024程序员节·单机游戏
非凡ghost2 小时前
Tenorshare 4DDiG(数据恢复软件) 最新版
前端·javascript·后端
非凡ghost3 小时前
WinMute(自动锁屏静音软件) 中文绿色版
前端·javascript·后端