推荐答案
在 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,可以编写出更加灵活和强大的类型工具。