推荐答案
在 TypeScript 中,infer
关键字通常用于条件类型中,用于推断类型变量。它的主要应用场景是在泛型类型中提取或推断出某个类型,从而在类型操作中使用。infer
通常与 extends
关键字一起使用,用于在条件类型中声明一个待推断的类型变量。
例如,在提取函数返回类型时,可以使用 infer
来推断函数的返回类型:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never; function foo(): number { return 42; } type FooReturnType = ReturnType<typeof foo>; // number
在这个例子中,ReturnType
类型通过 infer R
推断出函数 foo
的返回类型为 number
。
本题详细解读
1. infer
的基本用法
infer
关键字用于在条件类型中声明一个待推断的类型变量。它通常与 extends
关键字一起使用,表示在满足某个条件时,推断出某个类型。
例如:
type UnpackPromise<T> = T extends Promise<infer U> ? U : T; type A = UnpackPromise<Promise<string>>; // string type B = UnpackPromise<number>; // number
在这个例子中,UnpackPromise
类型通过 infer U
推断出 Promise
中的泛型类型 U
。如果 T
是一个 Promise
,则返回 U
,否则返回 T
本身。
2. infer
在函数类型中的应用
infer
在函数类型中的应用非常广泛,尤其是在提取函数参数类型或返回类型时。
例如,提取函数参数类型:
type Parameters<T> = T extends (...args: infer P) => any ? P : never; function bar(a: number, b: string): void {} type BarParams = Parameters<typeof bar>; // [number, string]
在这个例子中,Parameters
类型通过 infer P
推断出函数 bar
的参数类型为 [number, string]
。
3. infer
在数组类型中的应用
infer
也可以用于推断数组中的元素类型。
例如:
type ElementType<T> = T extends (infer U)[] ? U : never; type A = ElementType<string[]>; // string type B = ElementType<number[]>; // number
在这个例子中,ElementType
类型通过 infer U
推断出数组 T
中的元素类型 U
。
4. infer
在联合类型中的应用
infer
还可以用于推断联合类型中的某个类型。
例如:
type ExtractType<T> = T extends { type: infer U } ? U : never; type A = ExtractType<{ type: 'foo' }>; // 'foo' type B = ExtractType<{ type: 'bar' }>; // 'bar'
在这个例子中,ExtractType
类型通过 infer U
推断出对象 T
中的 type
属性的类型 U
。
5. infer
的限制
需要注意的是,infer
只能在条件类型的 extends
子句中使用,并且只能推断出一个类型变量。此外,infer
推断出的类型变量只能在条件类型的真分支中使用。
例如,以下代码是非法的:
type IllegalInfer<T> = infer U extends T ? U : never; // 错误:'infer' 只能在条件类型的 'extends' 子句中使用
6. 总结
infer
是 TypeScript 中一个强大的工具,用于在条件类型中推断类型变量。它在提取函数参数类型、返回类型、数组元素类型等方面有广泛的应用。通过合理使用 infer
,可以编写出更加灵活和强大的类型工具。