泛型

泛型把类型当作参数传入函数、接口与类型别名 等,在保持类型关系的前提下复用实现,避免为每种具体类型复制一份代码或退化成 any


泛型函数与推断

function first<T>(arr: T[]): T | undefined {
  return arr[0]
}
const n = first([1, 2]) // T 推断为 number
  • 显式实例化:first<number>([1, 2])
  • 多类型参数时推断可能「过宽」,必要时显式注解或加约束。

约束:extends

function keys<T extends object>(o: T) {
  return Object.keys(o) as (keyof T & string)[]
}
  • T extends U 表示:T 必须是 U 的子类型
  • 常与 keyof、索引访问类型 T[K] 组合,进入 高级类型

默认类型参数

interface Box<T = string> {
  value: T
}

泛型接口与泛型别名

interface Result<T, E> {
  ok: true
  value: T
}
type AsyncOp<T> = () => Promise<T>

接口与类型别名 的常规规则相同,仅多出类型实参列表。


泛型类

class Stack<T> {
  private a = [] as T[]
  push(x: T) {
    this.a.push(x)
  }
}

静态成员不能使用类类型参数 T(除非另有声明),这是常见易错点。


常见误区

  • 协变逆变:函数参数位置与返回值位置的子类型关系不完全对称;自定义复杂泛型 API 时需查手册或实验。
  • {}object:作约束时含义不同(基础类型)。

相关链接