Skip to content

工具类型 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 + 映射类型

系统学习 Web 前端生态,深入底层架构