TypeScript 的关键字 infer
文章类型:TypeScript
发布者:hp
发布时间:2025-03-13
infer 是 TypeScript 中用于 类型推断 的关键字,主要在 条件类型(extends 子句) 中声明临时类型变量,通过 反向推导 提取复杂类型的子类型或相关类型
其核心价值在于提升类型操作的灵活性和动态性
1:语法:若 T 符合 SomeType<U> 的结构,则 U 被自动推断为 T 中的子类型,推断成功时返回 U,失败时返回 NeverType
type Example<T> = T extends SomeType<infer U> ? U : NeverType;
2:流程
模式匹配:infer 根据条件类型中的类型结构进行模式匹配,如匹配函数的参数、返回值或 Promise 的泛型参数。
动态提取:将匹配成功的子类型赋值给 infer 声明的变量(如 U),供后续类型逻辑使用
1:动态提取类型信息
通过 infer 从泛型类型(如函数、Promise、数组等)中提取出具体的子类型(如参数、返回值、泛型参数等)
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
// 提取函数返回值类型,例如 ReturnType<() => number> → number
2:增强条件类型的表达能力
结合 extends 条件判断,根据类型结构动态生成新类型
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
// 解析 Promise 的泛型参数,例如 UnpackPromise<Promise<string>> → string
3:简化复杂类型操作
替代手动声明类型变量,减少冗余代码,提高可读性和可维护性
type ElementType<T> = T extends (infer U)[] ? U : T;
1:提取函数类型信息
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
// 例如 Parameters<(a: number, b: string) => void> → [number, string]
2:处理异步类型(Promise 和 Async)
type AsyncResult<T> = T extends Promise<infer U> ? U : never;
// 例如 AsyncResult<Promise<{ data: string }>> → { data: string }
3:操作数组和元组类型
type FirstElement<T> = T extends [infer First, ...any[]] ? First : never;
// 例如 FirstElement<[string, number]> → string
4:递归类型推断
type Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;
// 例如 Flatten<number[][]> → number
1:作用域限制:仅能在条件类型的 extends 子句中使用,不可单独声明
2:类型匹配失败处理:需通过条件分支(? :)处理推断失败的情况,避免类型错误
3:性能优化:避免在深层嵌套或复杂递归场景中滥用,可能影响类型检查速度