Skip to content

泛型和高级类型在面试里怎么讲? ​

泛型把类型当成参数,让输入和输出保持联系。高级类型是在已有类型上做运算:联合、交叉、条件、映射,以及 Partial、Pick 这些工具类型。它们都在编译期展开,运行时没有这些名字。

原理 ​

ts
function first<T>(list: T[]): T | undefined {
  return list[0]
}

T 由调用时的实参推断。约束写成 <T extends { id: string }>,函数里才能读 id。默认类型参数用 =。

条件类型 T extends U ? X : Y 按兼容关系选择。infer 能在条件里抽出一部分,例如函数返回值。分配条件类型遇到联合时会逐个分配,这是 Exclude 的原理。

映射类型遍历键:{ [K in keyof T]: ... }。Partial<T> 把每个属性变成可选,Pick<T, K> 只留下若干键,Record<K, V> 声明字典。keyof 取出键的联合。

unknown 要收窄再用。never 表示不会出现的分支,用来检查联合是否被穷尽。

追问 ​

和 any 的差别?

any 关掉检查。泛型在使用处仍是具体类型。拿不准外部数据时用 unknown,不要写成泛型的 T 却在内部当成任意字段去读。

条件类型什么时候会难读?

叠了两三层 infer 就该起一个名字,并配一个例子类型。面试写 ReturnType、Partial 的展开即可,不必背库里的全部定义。

易错点 ​

  • 泛型函数在实现里把 T 换成某个具体类型返回,调用方的推断就说谎了。
  • 以为 Partial 会把嵌套对象也变成可选。它只作用在第一层。
  • 运行时去读 keyof 的结果。擦除之后这些类型都不在。

相关 ​