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

参考更多资料:

相关推荐
Healer91820 分钟前
纯css实现高度0-auto动画过度interpolate-size 和 height: calc-size(auto,size)
前端
智慧源点20 分钟前
解决 Vite + React 项目部署 GitHub Pages 的完整指南:从 404 到成功部署
前端·react.js·github
葡萄城技术团队22 分钟前
浏览器端音视频处理新选择:Mediabunny 让 Web 媒体开发飞起来
前端·音视频·媒体
FogLetter24 分钟前
深入浅出 JavaScript 闭包:从背包理论到实战应用
前端·javascript
前端大卫1 小时前
表单与上传组件校验
前端·javascript·vue.js
伊织code1 小时前
Cap‘n Web - JavaScript原生RPC系统
前端·javascript·rpc
周尛先森2 小时前
匠心管控 package.json:让前端依赖告别臃肿与混乱
前端
90后的晨仔2 小时前
Vue3 事件处理详解:从入门到精通
前端·vue.js
西洼工作室2 小时前
设计模式与原则精要
前端·javascript·设计模式·vue
IT_陈寒2 小时前
SpringBoot 性能优化的 7 个冷门技巧,让你的应用快如闪电!
前端·人工智能·后端