infer 通常与条件类型结合使用,其语法形式如下:
T extends SomeType<infer U> ? X : Y
T extends SomeType<infer U>:表示在类型 T 满足 SomeType 条件的前提下,推断出 U 类型。X:当条件为真时,返回的类型(通常使用 U)。Y:当条件为假时,返回的类型。infer 常用于从复杂类型中提取出元素的类型。下面是一个从数组类型中提取出元素类型的示例。
type ElementType<T> = T extends (infer U)[] ? U : T;
type StringArray = ElementType<string[]>; // string
type NumberArray = ElementType<number[]>; // number
type NotArray = ElementType<string>; // string
解释:
T extends (infer U)[] 表示检查 T 是否是一个数组类型,如果是数组类型,则推断出 U 为数组元素的类型。StringArray 推断为 string,因为 string[] 是字符串数组,元素类型是 string。NotArray 不是数组类型,因此返回原始类型 string。你可以使用 infer 从函数类型中提取出参数或返回值的类型。
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
type MyFunction = (a: number, b: string) => boolean;
type Result = ReturnType<MyFunction>; // boolean
解释:
T extends (...args: any[]) => infer R 用来检查 T 是否是一个函数类型,如果是,则推断出 R 为返回值的类型。Result 推断为 boolean,因为 MyFunction 的返回值类型是 boolean。使用 infer 可以从元组类型中提取出第一个元素的类型。
type First<T> = T extends [infer U, ...any[]] ? U : never;
type Tuple1 = [number, string, boolean];
type FirstElement = First<Tuple1>; // number
解释:
T extends [infer U, ...any[]] 用来检查 T 是否是一个元组类型,并推断出 U 为元组的第一个元素的类型。FirstElement 推断为 number,因为 Tuple1 的第一个元素类型是 number。infer 还可以与联合类型结合,提取出联合类型中的具体类型。
type InferType<T> = T extends { a: infer A; b: infer B } ? A & B : never;
type ExampleType = { a: string; b: number };
type ResultType = InferType<ExampleType>; // string & number
解释:
T extends { a: infer A; b: infer B } 表示检查 T 是否具有 a 和 b 属性,并推断出 A 和 B 的类型。ResultType 推断为 string & number,表示 a 和 b 的交集类型。infer 关键字 是 TypeScript 中用于条件类型的一种工具,主要用于从复杂类型中推断或提取类型信息。通过 infer,你可以在类型层面进行灵活的类型推导,使得条件类型的应用更加强大和灵活。它通常用于泛型、函数类型和数组类型等场景。