Typescript中infer关键字的使用小结
infer 是 TypeScript 中条件类型的一个关键字,主要用于在条件类型中进行类型推断。它允许我们在泛型条件类型中声明一个类型变量,然后从其他类型中推断出这个类型。
基本语法
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
主要使用场景
1.获取函数返回类型
// 内置的 ReturnType 实现原理
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function foo(): string {
return "hello";
}
type FooReturn = MyReturnType<typeof foo>; // string
2.获取函数参数类型
// 获取第一个参数类型
type FirstParam<T> = T extends (first: infer P, ...rest: any[]) => any ? P : never;
// 获取所有参数类型(元组)
type Params<T> = T extends (...args: infer P) => any ? P : never;
function bar(x: number, y: string): void {}
type BarFirstParam = FirstParam<typeof bar>; // number
type BarParams = Params<typeof bar>; // [number, string]
3.获取数组/元组元素类型
typescript
type ArrayElement<T> = T extends (infer U)[] ? U : never; type StrArrayElement = ArrayElement<string[]>; // string type NumArrayElement = ArrayElement<number[]>; // number
4.获取 Promise 的解析类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; type PromiseString = Promise<string>; type Unwrapped = UnwrapPromise<PromiseString>; // string
实际应用示例
示例1:提取对象值类型
type ValueOf<T> = T extends { [key: string]: infer V } ? V : never;
type Obj = { a: number; b: string };
type Values = ValueOf<Obj>; // number | string
示例2:提取构造函数实例类型
type InstanceType<T> = T extends new (...args: any[]) => infer R ? R : any;
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
type AnimalInstance = InstanceType<typeof Animal>; // Animal
示例3:递归解包嵌套 Promise
type DeepUnwrapPromise<T> = T extends Promise<infer U> ? DeepUnwrapPromise<U> : T; type NestedPromise = Promise<Promise<string>>; type Result = DeepUnwrapPromise<NestedPromise>; // string
使用注意事项
1.只能用在条件类型的 extends 子句中
// ✅ 正确 type Example1<T> = T extends Array<infer U> ? U : never; // ❌ 错误:infer 不能单独使用 type Example2<T> = infer U; // 编译错误
2.多个 infer 可以同时使用
type Zip<T, U> = T extends [infer A, ...infer RestT]
? U extends [infer B, ...infer RestU]
? [[A, B], ...Zip<RestT, RestU>]
: []
: [];
type Result = Zip<[1, 2], ['a', 'b']>; // [[1, 'a'], [2, 'b']]
3.协变位置 vs 逆变位置
// infer 在协变位置(返回类型) type GetReturnType<T> = T extends () => infer R ? R : never; // infer 在逆变位置(参数类型) type GetArgType<T> = T extends (arg: infer A) => any ? A : never;
实战技巧
1.类型守卫与 infer
function isPromise<T>(value: any): value is Promise<T> {
return value && typeof value.then === 'function';
}
async function handle<T>(input: T | Promise<T>): Promise<T> {
if (isPromise(input)) {
// 这里 input 被推断为 Promise<T>
return input;
}
return Promise.resolve(input);
}
2.构建实用类型工具
// 提取所有方法的返回类型
type MethodsReturnType<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => infer R ? R : never;
};
// 提取特定属性的类型
type PropType<T, K extends keyof T> = T extends { [P in K]: infer V } ? V : never;
总结
infer 的核心作用:在条件类型中提取未知类型的内部结构。它是 TypeScript 类型系统的高级特性,常用于:
- 类型提取:从已有类型中提取部分类型信息
- 类型转换:将一个类型转换为另一种形式
- 类型推导:根据上下文推导出具体类型
- 工具类型创建:构建复杂的实用类型工具
掌握 infer 的关键是多实践,从简单的函数返回类型提取开始,逐步应用到更复杂的类型操作中。
到此这篇关于Typescript中infer关键字的使用小结的文章就介绍到这了,更多相关Typescript infer关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法
这篇文章主要介绍了webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-06-06
JS使用replace()方法和正则表达式进行字符串的搜索与替换实例
这篇文章主要介绍了JS使用replace()方法和正则表达式进行字符串的搜索与替换实例,需要的朋友可以参考下2014-04-04
js中将HTMLCollection/NodeList/伪数组转换成数组的代码
js中将HTMLCollection/NodeList/伪数组转换成数组的代码,需要的朋友可以参考下。2011-07-07


最新评论