目录基本语法主要使用场景1.获取函数返回类型2.获取函数参数类型3.获取数组/元组元素类型4.获取 Promise 的解析类型实际应用示例示例1:提取对象值类型示例2:提取构造函数实例类型示例3:递归解包嵌套 Promise使用注意事项1.只能用在条件类型的 extends 子句中2.多个 infer 可以同时使用3.协变位置 vs 逆变位置实战技巧1.类型守卫与 infer2.构建实用类型工具总结infer是 TypeScript 中条件类型的一个关键字,主要用于在条件类型中进行类型推断。它允许我们在泛
TypeScript中的infer关键字,本质上是在条件类型中进行类型推断的利器。它允许我们在泛型条件类型中声明一个类型变量,然后从其他类型的结构中自动推导出这个变量的具体类型。
type ReturnType= T extends (...args: any[]) => infer R ? R : never;
来看看如何提取函数的返回值类型:
// 内置的 ReturnType 实现原理 type MyReturnType= T extends (...args: any[]) => infer R ? R : never; function foo(): string { return "hello"; } type FooReturn = MyReturnType ; // string
函数参数的提取同样简单:
// 获取第一个参数类型 type FirstParam= T extends (first: infer P, ...rest: any[]) => any ? P : never; // 获取所有参数类型(元组) type Params = T extends (...args: infer P) => any ? P : never; function bar(x: number, y: string): void {} type BarFirstParam = FirstParam ; // number type BarParams = Params ; // [number, string]
处理数组类型时,infer同样得心应手:
type ArrayElement= T extends (infer U)[] ? U : never; type StrArrayElement = ArrayElement ; // string type NumArrayElement = ArrayElement ; // number
异步编程中,经常需要提取Promise的解析类型:
type UnwrapPromise= T extends Promise ? U : T; type PromiseString = Promise ; type Unwrapped = UnwrapPromise ; // string
想要从对象类型中提取所有值的联合类型?试试这个:
type ValueOf= T extends { [key: string]: infer V } ? V : never; type Obj = { a: number; b: string }; type Values = ValueOf ; // number | string
处理构造函数类型时,获取其实例类型很有用:
type InstanceType= T extends new (...args: any[]) => infer R ? R : any; class Animal { name: string; constructor(name: string) { this.name = name; } } type AnimalInstance = InstanceType ; // Animal
面对多层嵌套的Promise,递归解包才是王道:
type DeepUnwrapPromise= T extends Promise ? DeepUnwrapPromise : T; type NestedPromise = Promise >; type Result = DeepUnwrapPromise ; // string
记住,infer有它的使用边界:
// ? 正确 type Example1= T extends Array ? U : never; // ? 错误:infer 不能单独使用 type Example2 = infer U; // 编译错误
需要同时推断多个类型?完全没问题:
type Zip= T extends [infer A, ...infer RestT] ? U extends [infer B, ...infer RestU] ? [[A, B], ...Zip ] : [] : []; type Result = Zip<[1, 2], ['a', 'b']>; // [[1, 'a'], [2, 'b']]
理解类型推断的位置差异很重要:
// infer 在协变位置(返回类型) type GetReturnType= T extends () => infer R ? R : never; // infer 在逆变位置(参数类型) type GetArgType = T extends (arg: infer A) => any ? A : never;
结合类型守卫使用,能让代码更加类型安全:
function isPromise(value: any): value is Promise { return value && typeof value.then === 'function'; } async function handle (input: T | Promise ): Promise { if (isPromise(input)) { // 这里 input 被推断为 Promise return input; } return Promise.resolve(input); }
利用infer可以构建各种实用的类型工具:
// 提取所有方法的返回类型 type MethodsReturnType= { [K in keyof T]: T[K] extends (...args: any[]) => infer R ? R : never; }; // 提取特定属性的类型 type PropType = T extends { [P in K]: infer V } ? V : never;
说到底,infer的核心价值在于:在条件类型中提取未知类型的内部结构。作为TypeScript类型系统的高级特性,它在这些场景中尤其出色:
想要真正掌握infer?关键在于多动手实践。从简单的函数返回类型提取开始,逐步挑战更复杂的类型操作,很快你就能游刃有余了。
到此这篇关于Typescript中infer关键字的使用小结的文章就介绍到这了,更多相关Typescript infer关键字内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述