工具类型 Utility Types
TypeScript 内置了大量工具类型,掌握它们能大幅减少重复的类型定义。
对象操作
ts
interface User {
id: number
name: string
email: string
password: string
role: 'admin' | 'user'
createdAt: Date
}
// Partial<T>:所有属性变可选
type UserUpdate = Partial<User>
// { id?: number; name?: string; ... }
// Required<T>:所有属性变必填
type StrictUser = Required<Partial<User>>
// Readonly<T>:所有属性只读
type ImmutableUser = Readonly<User>
const user: ImmutableUser = { id: 1, name: 'Alice', ... }
// user.name = 'Bob' // ❌ 编译错误
// Pick<T, K>:选取指定属性
type UserPreview = Pick<User, 'id' | 'name'>
// { id: number; name: string }
// Omit<T, K>:排除指定属性
type PublicUser = Omit<User, 'password'>
// { id: number; name: string; email: string; role: ...; createdAt: Date }
// Record<K, V>:构造键值映射
type RolePermissions = Record<User['role'], string[]>
// { admin: string[]; user: string[] }
type UserById = Record<number, User>联合类型操作
ts
type Status = 'pending' | 'active' | 'inactive' | 'banned'
// Exclude<T, U>:从 T 中排除 U
type ActiveStatus = Exclude<Status, 'banned' | 'inactive'>
// 'pending' | 'active'
// Extract<T, U>:从 T 中提取 U
type NegativeStatus = Extract<Status, 'inactive' | 'banned'>
// 'inactive' | 'banned'
// NonNullable<T>:排除 null 和 undefined
type SafeString = NonNullable<string | null | undefined>
// string函数类型操作
ts
function createUser(name: string, age: number, role: 'admin' | 'user'): User {
return { id: Date.now(), name, email: '', password: '', role, createdAt: new Date() }
}
// ReturnType<T>:获取函数返回类型
type CreateUserResult = ReturnType<typeof createUser> // User
// Parameters<T>:获取函数参数类型(元组)
type CreateUserParams = Parameters<typeof createUser>
// [name: string, age: number, role: 'admin' | 'user']
// ConstructorParameters<T>:获取构造函数参数类型
class EventEmitter {
constructor(private maxListeners: number, private debug: boolean) {}
}
type EmitterParams = ConstructorParameters<typeof EventEmitter>
// [maxListeners: number, debug: boolean]
// InstanceType<T>:获取类的实例类型
type EmitterInstance = InstanceType<typeof EventEmitter>字符串操作类型
ts
// Uppercase / Lowercase / Capitalize / Uncapitalize
type Upper = Uppercase<'hello world'> // 'HELLO WORLD'
type Lower = Lowercase<'HELLO WORLD'> // 'hello world'
type Cap = Capitalize<'hello'> // 'Hello'
type Uncap = Uncapitalize<'Hello'> // 'hello'
// 实际应用:生成事件处理器类型
type EventNames = 'click' | 'focus' | 'blur' | 'change'
type Handlers = {
[K in EventNames as `on${Capitalize<K>}`]: (event: Event) => void
}
// { onClick: ...; onFocus: ...; onBlur: ...; onChange: ... }手写常用工具类型
ts
// DeepPartial:深度可选
type DeepPartial<T> = T extends object
? { [K in keyof T]?: DeepPartial<T[K]> }
: T
// DeepReadonly:深度只读
type DeepReadonly<T> = T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T
// Mutable:移除 readonly
type Mutable<T> = { -readonly [K in keyof T]: T[K] }
// PickByValue:按值类型选取属性
type PickByValue<T, V> = {
[K in keyof T as T[K] extends V ? K : never]: T[K]
}
interface Mixed {
id: number
name: string
active: boolean
count: number
}
type StringProps = PickByValue<Mixed, string> // { name: string }
type NumberProps = PickByValue<Mixed, number> // { id: number; count: number }
// Flatten:展平嵌套数组类型
type Flatten<T> = T extends Array<infer U> ? Flatten<U> : T
type R = Flatten<number[][][]> // number
// UnionToIntersection:联合转交叉
type UnionToIntersection<U> =
(U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never
type A = { a: string }
type B = { b: number }
type AB = UnionToIntersection<A | B> // { a: string } & { b: number }实战:API 类型系统
ts
// 通用 API 响应类型
type ApiResponse<T> = {
data: T
message: string
code: number
}
type PaginatedResponse<T> = ApiResponse<{
list: T[]
total: number
page: number
pageSize: number
}>
// 从接口定义自动生成请求/响应类型
interface UserApi {
'GET /users': {
query: { page?: number; pageSize?: number; keyword?: string }
response: PaginatedResponse<User>
}
'GET /users/:id': {
params: { id: number }
response: ApiResponse<User>
}
'POST /users': {
body: Omit<User, 'id' | 'createdAt'>
response: ApiResponse<User>
}
'PATCH /users/:id': {
params: { id: number }
body: Partial<Omit<User, 'id' | 'createdAt'>>
response: ApiResponse<User>
}
}
// 类型安全的请求函数
async function request<K extends keyof UserApi>(
endpoint: K,
options: Omit<UserApi[K], 'response'>
): Promise<UserApi[K]['response']> {
// 实现...
}总结
Partial/Required/Readonly/Pick/Omit/Record是日常必备ReturnType/Parameters从函数推导类型,避免重复定义Exclude/Extract/NonNullable操作联合类型- 手写工具类型时,善用条件类型 +
infer+ 映射类型