Skip to content

TypeScript 高级类型系统深度解析

TypeScript 的类型系统是其最强大的特性之一。本文将深入探讨 TypeScript 的高级类型特性,帮助你编写更安全、更优雅的代码。

泛型 (Generics)

基础泛型

typescript
// 基础泛型函数
function identity<T>(arg: T): T {
  return arg
}

// 使用
const result1 = identity<string>('hello') // string
const result2 = identity(42) // number (类型推断)

// 泛型接口
interface GenericIdentityFn<T> {
  (arg: T): T
}

const myIdentity: GenericIdentityFn<number> = identity

泛型约束

typescript
// 约束泛型必须有 length 属性
interface Lengthwise {
  length: number
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length)
  return arg
}

// 使用
loggingIdentity('hello') // ✅ string 有 length
loggingIdentity([1, 2, 3]) // ✅ array 有 length
// loggingIdentity(3) // ❌ number 没有 length

// 使用 keyof 约束
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key]
}

const person = { name: 'John', age: 30, city: 'New York' }
const name = getProperty(person, 'name') // string
const age = getProperty(person, 'age') // number

条件类型 (Conditional Types)

基础条件类型

typescript
// 基础语法:T extends U ? X : Y
type IsString<T> = T extends string ? true : false

type Test1 = IsString<string> // true
type Test2 = IsString<number> // false

// 实用的条件类型
type NonNullable<T> = T extends null | undefined ? never : T

type Test3 = NonNullable<string | null> // string
type Test4 = NonNullable<number | undefined> // number

分布式条件类型

typescript
// 当条件类型作用于联合类型时,会分布式应用
type ToArray<T> = T extends any ? T[] : never

type Test5 = ToArray<string | number> // string[] | number[]

// 排除类型
type Exclude<T, U> = T extends U ? never : T
type Test6 = Exclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'

// 提取类型
type Extract<T, U> = T extends U ? T : never
type Test7 = Extract<'a' | 'b' | 'c', 'a' | 'f'> // 'a'

infer 关键字

typescript
// 推断函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any

type Test8 = ReturnType<() => string> // string
type Test9 = ReturnType<(x: number) => number> // number

// 推断数组元素类型
type ArrayElementType<T> = T extends (infer U)[] ? U : never

type Test10 = ArrayElementType<string[]> // string
type Test11 = ArrayElementType<number[]> // number

// 推断 Promise 类型
type PromiseType<T> = T extends Promise<infer U> ? U : never

type Test12 = PromiseType<Promise<string>> // string

映射类型 (Mapped Types)

基础映射类型

typescript
// 基础语法
type Readonly<T> = {
  readonly [P in keyof T]: T[P]
}

type Partial<T> = {
  [P in keyof T]?: T[P]
}

type Required<T> = {
  [P in keyof T]-?: T[P]
}

// 使用示例
interface User {
  id: number
  name: string
  email?: string
}

type ReadonlyUser = Readonly<User>
type PartialUser = Partial<User>
type RequiredUser = Required<User>

高级映射类型

typescript
// 键名映射
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
}

type UserGetters = Getters<User>
// {
//   getId: () => number
//   getName: () => string
//   getEmail: () => string | undefined
// }

// 过滤属性
type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K]
}

type StringProperties = PickByType<User, string>
// { name: string; email?: string }

// 排除属性
type OmitByType<T, U> = {
  [K in keyof T as T[K] extends U ? never : K]: T[K]
}

type NonStringProperties = OmitByType<User, string>
// { id: number }

模板字面量类型

typescript
// 基础模板字面量
type World = 'world'
type Greeting = `hello ${World}` // 'hello world'

// 结合联合类型
type Color = 'red' | 'green' | 'blue'
type Quantity = 'one' | 'two' | 'three'
type SeussFish = `${Quantity | Color} fish`
// 'one fish' | 'two fish' | 'three fish' | 'red fish' | 'green fish' | 'blue fish'

// 实用示例:事件名称
type EventName<T extends string> = `on${Capitalize<T>}`
type ClickEvent = EventName<'click'> // 'onClick'
type HoverEvent = EventName<'hover'> // 'onHover'

// CSS 属性
type CSSProperty = 'margin' | 'padding'
type CSSDirection = 'top' | 'right' | 'bottom' | 'left'
type LonghandProperty = `${CSSProperty}-${CSSDirection}`
// 'margin-top' | 'margin-right' | 'margin-bottom' | 'margin-left' | ...

实用工具类型

深度操作类型

typescript
// 深度只读
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]
}

// 深度可选
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]
}

// 深度必需
type DeepRequired<T> = {
  [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P]
}

interface NestedUser {
  id: number
  profile: {
    name: string
    avatar?: string
    settings: {
      theme: string
      notifications?: boolean
    }
  }
}

type ReadonlyNestedUser = DeepReadonly<NestedUser>
type PartialNestedUser = DeepPartial<NestedUser>

函数类型工具

typescript
// 获取函数参数类型
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never

// 构造函数参数类型
type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never

// 实例类型
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any

// 使用示例
function createUser(name: string, age: number): User {
  return { id: 1, name, age }
}

type CreateUserParams = Parameters<typeof createUser> // [string, number]
type CreateUserReturn = ReturnType<typeof createUser> // User

class UserClass {
  constructor(public name: string, public age: number) {}
}

type UserConstructorParams = ConstructorParameters<typeof UserClass> // [string, number]
type UserInstance = InstanceType<typeof UserClass> // UserClass

高级应用场景

API 响应类型生成

typescript
// 基础 API 响应结构
interface ApiResponse<T> {
  code: number
  message: string
  data: T
}

// 分页响应
interface PaginatedResponse<T> {
  items: T[]
  total: number
  page: number
  pageSize: number
}

// 组合类型
type PaginatedApiResponse<T> = ApiResponse<PaginatedResponse<T>>

// 使用
type UserListResponse = PaginatedApiResponse<User>

状态管理类型

typescript
// 状态类型
interface AppState {
  user: User | null
  posts: Post[]
  loading: boolean
  error: string | null
}

// Action 类型
type ActionType = 'SET_USER' | 'SET_POSTS' | 'SET_LOADING' | 'SET_ERROR'

// Action 创建器类型
type ActionCreator<T extends ActionType, P = void> = P extends void
  ? () => { type: T }
  : (payload: P) => { type: T; payload: P }

// 具体 Action
type SetUserAction = ActionCreator<'SET_USER', User>
type SetPostsAction = ActionCreator<'SET_POSTS', Post[]>
type SetLoadingAction = ActionCreator<'SET_LOADING', boolean>
type SetErrorAction = ActionCreator<'SET_ERROR', string>

// 联合 Action 类型
type AppAction = 
  | ReturnType<SetUserAction>
  | ReturnType<SetPostsAction>
  | ReturnType<SetLoadingAction>
  | ReturnType<SetErrorAction>

表单验证类型

typescript
// 验证规则类型
type ValidationRule<T> = {
  required?: boolean
  min?: T extends string ? number : T extends number ? number : never
  max?: T extends string ? number : T extends number ? number : never
  pattern?: T extends string ? RegExp : never
  custom?: (value: T) => string | undefined
}

// 表单配置类型
type FormConfig<T> = {
  [K in keyof T]: ValidationRule<T[K]>
}

// 验证结果类型
type ValidationResult<T> = {
  [K in keyof T]?: string
}

// 使用示例
interface LoginForm {
  email: string
  password: string
  age: number
}

const loginConfig: FormConfig<LoginForm> = {
  email: {
    required: true,
    pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  },
  password: {
    required: true,
    min: 6,
    max: 20
  },
  age: {
    required: true,
    min: 18,
    max: 120
  }
}

性能优化技巧

避免过度复杂的类型

typescript
// ❌ 避免:过度复杂的递归类型
type BadDeepMerge<T, U> = {
  [K in keyof T | keyof U]: K extends keyof T
    ? K extends keyof U
      ? T[K] extends object
        ? U[K] extends object
          ? BadDeepMerge<T[K], U[K]>
          : U[K]
        : U[K]
      : T[K]
    : K extends keyof U
    ? U[K]
    : never
}

// ✅ 好的做法:简化类型定义
type SimpleMerge<T, U> = Omit<T, keyof U> & U

使用类型断言和类型守卫

typescript
// 类型守卫
function isString(value: unknown): value is string {
  return typeof value === 'string'
}

function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' &&
    value !== null &&
    'id' in value &&
    'name' in value
  )
}

// 使用
function processValue(value: unknown) {
  if (isString(value)) {
    // value 的类型现在是 string
    console.log(value.toUpperCase())
  }
  
  if (isUser(value)) {
    // value 的类型现在是 User
    console.log(value.name)
  }
}

总结

TypeScript 的高级类型系统为我们提供了强大的工具来构建类型安全的应用程序。通过掌握这些高级特性,我们可以:

  1. 提高代码质量:通过精确的类型定义减少运行时错误
  2. 改善开发体验:获得更好的 IDE 支持和自动补全
  3. 增强代码可维护性:类型作为文档,帮助理解代码意图
  4. 实现更好的重构支持:类型系统帮助安全地重构代码

记住,类型系统的目标是帮助我们编写更好的代码,而不是增加复杂性。在实际项目中,要根据具体需求选择合适的类型策略,避免过度工程化。

用代码构建未来,让技术改变世界 🚀 | 专注前端技术,分享开发经验