TypeScript 提供了一系列内置高级类型工具,可通过泛型参数灵活处理类型转换与提取。本章将以"工具手册"形式详解常用工具的使用方法,并通过实际案例演示组合应用,最后引导实现自定义类型工具。
作用:将泛型参数 T 中的所有属性转换为可选属性。
语法:type Partial<T> = { [P in keyof T]?: T[P] }(TypeScript 内置实现)。
示例:
定义用户接口 User 后,通过 Partial<User> 生成所有属性可选的类型:
interface User {
name: string;
age: number;
email: string;
}
// 所有属性变为可选:{ name?: string; age?: number; email?: string }
type PartialUser = Partial<User>;
应用:主要用于表单更新场景。当用户提交部分字段修改时(如仅更新姓名或年龄),无需传递完整对象,提升接口灵活性。
注意:Partial<T> 仅对对象的直接属性生效,若属性值为嵌套对象,嵌套对象的属性不会自动变为可选。如需深度可选,需实现递归版本的 DeepPartial<T>。
作用:从泛型参数 T 中提取指定属性 K(K 必须为 T 的属性键集合),生成仅包含这些属性的新类型。
语法:type Pick<T, K extends keyof T> = { [P in K]: T[P] }(TypeScript 内置实现)。
示例:
从 User 接口中仅提取 name 和 age 属性:
// 仅包含 name 和 age:{ name: string; age: number }
type UserNameAge = Pick<User, 'name' | 'age'>;
应用:适用于API 响应数据过滤。后端返回数据可能包含冗余字段,通过 Pick 可精确筛选前端所需字段,减少数据传输量并提升类型安全性。
单独使用高级类型工具可满足基础需求,而组合使用能解决更复杂场景。例如,通过 Partial<Pick<T, K>> 可实现"从 T 中选取部分属性并将其变为可选"的效果。
案例:用户信息编辑 API
假设需要设计一个用户信息编辑接口,要求:
可通过以下类型设计实现:
// 1. 定义基础用户类型
interface User {
id: number;
name: string;
age: number;
email: string;
createdAt: Date; // 无需前端修改的字段
}
// 2. 请求参数类型:可选修改 name 和 age
type UpdateUserRequest = Partial<Pick<User, 'name' | 'age'>>;
// 等价于:{ name?: string; age?: number }
// 3. 响应类型:仅返回必要字段
type UpdateUserResponse = Pick<User, 'id' | 'name' | 'age'>;
// 等价于:{ id: number; name: string; age: number }
效果:
{ name: "新名称" } 或 { age: 25 },接口仍能正常处理; id、name、age,避免暴露 email、createdAt 等敏感或冗余信息。目标:创建类型工具 ExcludeNull<T>,移除联合类型 T 中的 null 类型。
思路:使用 TypeScript 条件类型 T extends null ? never : T,若 T 为 null 则返回 never(表示排除该类型),否则保留原类型。
实现代码:
type ExcludeNull<T> = T extends null ? never : T;
// 测试用例
type Test1 = ExcludeNull<string | number | null>; // 结果:string | number
type Test2 = ExcludeNull<boolean | null | undefined>; // 结果:boolean | undefined
type Test3 = ExcludeNull<null>; // 结果:never(无有效类型)
说明:ExcludeNull 可用于净化可能包含 null 的数据类型,例如处理后端返回的可能为 null 的字段,确保前端使用时类型更安全。