泛型

使用场景

泛型约束

确保属性存在

没有进行约束,访问属性,会报错:

function trace<T>(arg: T): T {
  console.log(arg.size); // Error: Property 'size doesn't exist on type 'T'
}

使用 extends 关键字进行约束:

interface Sizeable {
  size: number;
}

function trace<T extends Sizeable>(arg: T): T {
  console.log(arg.size);
}

检查对象上的键是否存在

限制输入的属性名包含在 keyof 返回的联合类型中:

// 确保参数 key 一定是对象中含有的键
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

条件类型

以一个条件表达式进行类型关系检测,从而在两种类型中选择其一:

// 若 T 能够赋值给 U,那么类型是 X,否则为 Y
T extends U ? X : Y

通常还会结合 infer 关键字,实现类型抽取:

interface Dictionary<T = any> {
  [key: string]: T;
}

type StrDict = Dictionary<string>;

type DictMember<T> = T extends Dictionary<infer V> ? V : never;
type StrDictMember = DictMember<StrDict>; // string