TypeScript 内置了大量实用的工具类型(Utility Types),日常开发中几乎每天都会用到。掌握这些内置工具类型可以大幅减少重复的类型定义,让代码更简洁、类型更安全。本文列出最常用的 12 个内置工具类型及其典型用法。
// TypeScript 内置工具类型速查 -- 日常最常用的 12 个
interface User {
id: number;
name: string;
email: string;
age?: number;
readonly createdAt: Date;
}
// 1. Partial<T> -- 所有属性变为可选
type PartialUser = Partial<User>;
// { id?: number; name?: string; email?: string; age?: number; readonly createdAt?: Date }
// 场景:表单更新、配置合并
// 2. Required<T> -- 所有属性变为必填
type RequiredUser = Required<User>;
// { id: number; name: string; email: string; age: number; readonly createdAt: Date }
// 场景:确保所有字段都有值
// 3. Readonly<T> -- 所有属性变为只读
type ReadonlyUser = Readonly<User>;
// 场景:不可变数据、Redux state
// 4. Pick<T, K> -- 从 T 中挑选指定属性
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: number; name: string }
// 场景:列表项只展示部分字段
// 5. Omit<T, K> -- 从 T 中排除指定属性
type UserWithoutEmail = Omit<User, 'email'>;
// { id: number; name: string; age?: number; readonly createdAt: Date }
// 场景:创建用户时不传 email
// 6. Record<K, V> -- 构造键为 K、值为 V 的对象类型
type UserMap = Record<string, User>;
// { [key: string]: User }
type StatusMap = Record<'active' | 'inactive' | 'banned', string>;
// 场景:字典映射、枚举 label 映射
// 7. Extract<T, U> -- 从 T 中提取可赋值给 U 的类型
type A = string | number | boolean;
type StrOrNum = Extract<A, string | number>; // string | number
// 场景:从联合类型中筛选子类型
// 8. Exclude<T, U> -- 从 T 中排除可赋值给 U 的类型
type NotBool = Exclude<A, boolean>; // string | number
// 场景:剔除特定类型
// 9. ReturnType<T> -- 提取函数返回值类型
function getUser() { return { id: 1, name: 'Alice' }; }
type UserReturn = ReturnType<typeof getUser>; // { id: number; name: string }
// 场景:从已有函数推导返回值类型
// 10. Parameters<T> -- 提取函数参数类型(元组)
function updateUser(id: number, data: Partial<User>) {}
type UpdateParams = Parameters<typeof updateUser>;
// [number, Partial<User>]
// 11. Awaited<T> -- 递归解包 Promise
type P = Promise<Promise<string>>;
type Unwrapped = Awaited<P>; // string
// 场景:async 函数返回值类型推导
// 12. NonNullable<T> -- 从类型中排除 null 和 undefined
type MaybeString = string | null | undefined;
type DefiniteString = NonNullable<MaybeString>; // string
// 场景:过滤掉 nullable 类型
Partial、Required、Readonly 都是对对象属性做批量修改,底层使用映射类型 [K in keyof T] 实现。Pick 和 Omit 按属性名筛选,Pick 是"只要这几个",Omit 是"不要这几个"。Extract 和 Exclude 作用于联合类型,Extract 是"取交集",Exclude 是"差集"。ReturnType 和 Parameters 是提取函数类型信息的利器,配合 typeof 使用。Record<K, V> 是 { [P in K]: V } 的简写,用于快速定义键值映射类型。// 实战:组合使用内置工具类型
interface ApiUser {
id: number;
name: string;
email: string;
password: string;
createdAt: string;
updatedAt: string;
}
// 前端展示用:去掉敏感字段
type SafeUser = Omit<ApiUser, 'password'>;
// 创建用户表单:id 和时间戳都自动生成
type CreateUserForm = Omit<ApiUser, 'id' | 'createdAt' | 'updatedAt'>;
// 更新用户表单:所有字段可选
type UpdateUserForm = Partial<Omit<ApiUser, 'id' | 'createdAt'>>;
// 字典映射:状态码到中文描述
type StatusCode = 'pending' | 'processing' | 'done' | 'failed';
const statusLabels: Record<StatusCode, string> = {
pending: '待处理',
processing: '处理中',
done: '已完成',
failed: '失败',
};