9. infer 关键字的用途
约 722 字大约 2 分钟
2025-06-09
infer
是 TypeScript 中用于 条件类型 内部进行类型推断的关键字,它允许你在泛型条件类型中声明一个待推断的类型变量,是高级类型操作的核心工具之一。
基本概念
infer
只能在 extends
条件类型的子句中使用,用于声明一个需要推断的类型位置:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
比如这里的 R
,就是一个待推断的类型变量。我们不知道 (...args: any[]) => infer R
具体返回什么类型,我们可以是 R
来代替,然后在后面使用 R
来表示这个类型。
注意事项
infer
只能在条件类型的extends
子句中使用- 每个
infer
声明必须对应一个类型变量 - 复杂的
infer
操作可能会影响编译性能 - 推断结果受类型变体(协变/逆变)规则影响
主要用途
1. 提取函数返回类型
type MyReturnType<T> = T extends (...args: any) => infer R ? R : never;
function foo() {
return 123;
}
type FooReturn = MyReturnType<typeof foo>; // number
2. 提取函数参数类型
type ParamType<T> = T extends (arg: infer P) => any ? P : never;
function bar(x: string) {}
type BarParam = ParamType<typeof bar>; // string
3. 提取数组/元组元素类型
type ArrayItem<T> = T extends (infer U)[] ? U : never;
type TupleFirst<T> = T extends [infer F, ...any[]] ? F : never;
type NumArray = number[];
type Item = ArrayItem<NumArray>; // number
type Pair = [string, number];
type First = TupleFirst<Pair>; // string
4. 提取 Promise 的解析类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type PromisedString = Promise<string>;
type Resolved = UnwrapPromise<PromisedString>; // string
高级用法
1. 递归类型解包
type DeepUnwrapPromise<T> = T extends Promise<infer U>
? DeepUnwrapPromise<U>
: T;
type Promised = Promise<Promise<number>>;
type Unwrapped = DeepUnwrapPromise<Promised>; // number
2. 联合类型推断
type UnionFromArray<T> = T extends (infer U)[] ? U : never;
type Values = UnionFromArray<[string, number, boolean]>; // string | number | boolean
3. 提取构造函数实例类型
type InstanceType<T> = T extends new (...args: any) => infer R ? R : any;
class MyClass {}
type MyInstance = InstanceType<typeof MyClass>; // MyClass
特殊行为
协变位置推断(如函数返回类型):
type CoVariant<T> = T extends () => infer R ? R : never; // 会推断出最具体的类型
逆变位置推断(如函数参数类型):
type ContraVariant<T> = T extends (arg: infer P) => any ? P : never; // 会推断出最宽泛的类型(遵循类型安全)
实用案例
1. 提取 React 组件 Props 类型
type PropsOf<T> = T extends React.ComponentType<infer P> ? P : never;
function MyComponent(props: { name: string }) {}
type MyProps = PropsOf<typeof MyComponent>; // { name: string }
2. 递归解构嵌套对象
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
3. 类型安全的装饰器
type DecoratedMethod<T> = T extends (...args: infer A) => infer R
? (this: any, ...args: A) => R
: never;
infer
是 TypeScript 类型编程中最强大的工具之一,它使得类型系统具备了类似模式匹配的能力,可以动态地提取和操作复杂类型的内部结构。
更新日志
2025/8/24 08:17
查看所有更新日志
e7112
-1于