TypeScript 提供了一系列内置的“工具类型”(Utility Types),它们是对已有类型进行变换的便捷方式。通过这些工具类型,开发者可以更灵活、可维护地进行类型设计,避免重复定义类型逻辑。
工具类型的作用主要有:
- 快速基于已有类型创建新类型;
- 控制属性的可选性、只读性、选择性;
- 提升代码可读性与复用性。
下面,我们将详细讲解 TypeScript 提供的常用工具类型及其应用示例。
一、Partial<Type>
作用:将某个类型的所有属性变为可选。
语法:
Partial<T>
示例:
interface User {Id: string;email: string;
}type PartialUser = Partial<User>;const partialUser: PartialUser = { Id: '123' };console.log(partialUser); // 输出: { Id: '123' }
说明:
PartialUser
中的所有属性都是可选的。partialUser
只传入了Id
属性也合法。
二、Required<Type>
作用:将某个类型中的所有属性变为必填。
语法:
Required<T>
示例:
interface User {name?: string;age?: number;
}type RequiredUser = Required<User>;const requiredUser: RequiredUser = { name: 'John', age: 20 };console.log(requiredUser); // 输出: { name: 'John', age: 20 }
说明:
RequiredUser
中的所有属性都变成了必填。- 缺少任何属性都会报错。
三、Readonly<Type>
作用:将类型中所有属性标记为只读,禁止修改。
语法:
Readonly<T>
示例:
interface User {name: string;age: number;
}type ReadonlyUser = Readonly<User>;const readonlyUser: ReadonlyUser = { name: 'John', age: 30 };readonlyUser.name = 'Jane';
// 报错:Cannot assign to 'name' because it is a read-only property.
说明:
ReadonlyUser
的属性不能被修改。- 用于实现对象的不可变性。
四、Pick<Type, Keys>
作用:从类型 T 中挑选出一组指定的属性,构成新类型。
语法:
Pick<T, K>
示例:
interface User {name: string;age: number;email: string;
}type UserSummary = Pick<User, 'name' | 'email'>;const userSummary: UserSummary = { name: 'ram', email: 'ram@example.com' };console.log(userSummary); // 输出: { name: 'ram', email: 'ram@example.com' }
说明:
- 只选择了
User
中的name
和email
属性。
五、Parameters<Type>
作用:提取函数类型中所有参数类型,组成元组类型。
语法:
Parameters<T>
示例:
function sum(a: number, b: number): number {return a + b;
}type SumParams = Parameters<typeof sum>; // [number, number]const params: SumParams = [1, 2];console.log(params); // 输出: [1, 2]
说明:
SumParams
是一个元组类型[number, number]
。- 可以动态地从函数中提取参数类型进行复用。
六、Record<Keys, Type>
作用:构建一个具有固定 key 的对象类型,所有 key 对应的值都是指定的类型。
语法:
Record<K, T>
示例:
type Fruit = 'apple' | 'banana' | 'orange';type Inventory = Record<Fruit, number>;const inventory: Inventory = {apple: 10,banana: 15,orange: 20
};console.log(inventory);
// 输出: { apple: 10, banana: 15, orange: 20 }
说明:
Inventory
是一个 key 为水果名,value 为数量的对象。- 保证所有 key 都存在,且值为 number 类型。
七、Exclude<Type, ExcludedUnion>
作用:从联合类型 T 中排除掉属于 U 的部分。
语法:
Exclude<T, U>
示例:
type Status = 'pending' | 'approved' | 'rejected';type NonRejectedStatus = Exclude<Status, 'rejected'>;const status: NonRejectedStatus = 'approved';console.log(status); // 输出: approved
说明:
NonRejectedStatus
只包含'pending'
和'approved'
,排除了'rejected'
。- 如果赋值为
'rejected'
会报错。
八、使用建议和最佳实践
- 理解每种工具类型的用途:如
Partial
用于表单、更新操作,Readonly
用于不可变数据。 - 保持类型一致性:统一使用工具类型能让代码更具可读性。
- 合理组合工具类型:可以
Pick
再Readonly
,但避免过度嵌套造成难以维护。
九、总结
TypeScript 的工具类型为我们提供了一套强大且灵活的类型变换机制,可以让类型定义更加精简、强大而不失可读性。无论是在业务模型构建、表单设计还是 API 数据转换中,它们都能大幅提升代码的开发效率与维护质量。
推荐使用场景包括:
- 接口部分字段可选(使用
Partial
) - 创建只读数据模型(使用
Readonly
) - 提取函数参数、返回值类型(使用
Parameters
,ReturnType
) - 对接口类型取子集(使用
Pick
,Omit
) - 创建特定 key 的对象(使用
Record
)
充分掌握这些工具类型,是成为 TypeScript 高效开发者的必经之路。