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
,你可以在类型层面进行灵活的类型推导,使得条件类型的应用更加强大和灵活。它通常用于泛型、函数类型和数组类型等场景。