Typescript中infer关键字详解——基本原理+应用场景

以下是关于 TypeScript 中 infer 关键字的详细解析,涵盖其核心原理、应用场景和实际示例:


一、infer 的基本原理

infer 是 TypeScript 条件类型(Conditional Types)中的关键字,用于在类型匹配时动态推断并捕获类型信息。它必须与 extends 结合使用,语法如下:

type MyType<T> = T extends SomePattern<infer U> ? U : NeverType;

• 核心逻辑:若 T 匹配 SomePattern 的结构,则 infer U 会提取 U 的类型,否则返回备选类型(如 neverany)。

• 特点:

• 仅能在条件类型中使用,无法单独声明类型变量;

• 推断的类型变量仅在 ? 后的分支中有效,无法脱离作用域。


二、常见应用场景

1. 提取函数类型信息

• 返回值类型:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type FnReturn = ReturnType<() => number>; // number 

• 参数类型:

type Parameters<T> = T extends (...args: infer P) => any ? P : never;
type FnParams = Parameters<(x: number, y: string) => void>; // [number, string] 
2. 处理数组与元组

• 元素类型提取:

type ElementType<T> = T extends (infer U)[] ? U : never;
type NumElement = ElementType<number[]>; // number 

• 元组操作:

type FirstElement<T> = T extends [infer F, ...any[]] ? F : never;
type First = FirstElement<[number, string]>; // number 
3. 解构 Promise 和对象

• Promise 结果类型:

type UnpackPromise<T> = T extends Promise<infer R> ? R : never;
type PromiseResult = UnpackPromise<Promise<string>>; // string 

• 对象属性类型:

type PropType<T, K extends keyof T> = T extends { [P in K]: infer V } ? V : never;
type Age = PropType<{ age: number }, "age">; // number 
4. 字符串模板类型操作

• 提取前缀/后缀:

type Prefix<T> = T extends `${infer P}_${string}` ? P : never;
type Pre = Prefix<"hello_world">; // "hello" 

三、高级用法

1. 递归处理嵌套结构

• 展平嵌套数组:

type Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;
type FlatArr = Flatten<number[][][]>; // number 
2. 联合类型筛选

• 提取特定类型成员:

type ExtractStrings<T> = T extends infer U ? (U extends string ? U : never) : never;
type StrOnly = ExtractStrings<string | number>; // string 
3. 深度类型解构

• 多层对象属性提取:

type DeepProp<T> = T extends { a: infer A; b: { c: infer C } } ? [A, C] : never;
type Result = DeepProp<{ a: string; b: { c: number } }>; // [string, number] 

四、注意事项与限制

  1. 作用域限制:infer 仅在条件类型的分支中有效,无法全局使用。
  2. 模式匹配限制:无法处理不符合结构或模糊的类型(如非元组数组)。
  3. 复杂度控制:过度嵌套可能导致类型推导难以维护。

五、总结

infer 是 TypeScript 类型系统的核心工具之一,通过动态类型推断大幅提升了类型操作的灵活性。其典型应用包括:
• 函数类型解构(参数、返回值);

• 容器类型提取(数组、Promise);

• 字符串模板处理;

• 递归与联合类型操作。

结合具体场景合理使用 infer,可以显著增强代码的类型安全性和可维护性。更多高级用法可参考 TypeScript 官方文档或类型工具库(如 utility-types)。


在 TypeScript 中,infer 是一个强大的关键字,用于在条件类型(Conditional Types)中推断类型信息。它允许我们在类型系统中进行模式匹配,并从复杂的类型结构中提取特定的类型部分,从而实现更灵活和可复用的类型定义。(CSDN博客)


🔍 基本语法

infer 通常与条件类型一起使用,其基本语法如下:(CSDN博客)

type ExtractType<T> = T extends SomeType<infer U> ? U : DefaultType;

在这个结构中:

  • T 是待推断的类型。
  • SomeType<infer U> 是用于匹配 T 的类型模式。
  • U 是通过 infer 关键字推断出的类型变量。
  • 如果 T 能匹配 SomeType<infer U> 的模式,则返回 U;否则返回 DefaultType。(杰克超, CSDN博客)

🛠️ 常见应用场景

1. 提取函数参数类型
type ParamType<T> = T extends (arg: infer P) => any ? P : never;

type ExampleFunc = (x: number) => void;
type Param = ParamType<ExampleFunc>; // Param 的类型为 number
2. 提取函数返回值类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

type ExampleFunc = () => string;
type Result = ReturnType<ExampleFunc>; // Result 的类型为 string
3. 提取数组元素类型
type ElementType<T> = T extends Array<infer E> ? E : never;

type ExampleArray = number[];
type Element = ElementType<ExampleArray>; // Element 的类型为 number
4. 提取 Promise 的解析类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type ExamplePromise = Promise<string>;
type Result = UnwrapPromise<ExamplePromise>; // Result 的类型为 string
5. 提取元组的第一个元素类型
type FirstElement<T extends any[]> = T extends [infer First, ...any[]] ? First : never;

type ExampleTuple = [string, number, boolean];
type First = FirstElement<ExampleTuple>; // First 的类型为 string

📚 深入理解

infer 的强大之处在于它能够在类型系统中进行模式匹配和类型推断,从而实现更复杂的类型操作。例如,可以使用 infer 将联合类型转换为交叉类型,或者从复杂的嵌套类型中提取特定的类型信息。(CSDN博客)

此外,TypeScript 内置了一些使用 infer 的类型工具,如 ReturnType<T>Parameters<T>ConstructorParameters<T>InstanceType<T> 等,这些工具类型在日常开发中非常实用。(杰克超)


📖 参考资料


如果您对某个具体的使用场景或示例感兴趣,欢迎继续提问!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GISer_Jinger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值