infer

2026 年 2 月 18 日 星期三
/ ,
2

infer

目录

  • 什么是 infer
  • 基础用法:在条件类型中推断类型
  • 常见场景与示例
    • 提取函数返回值类型
    • 提取参数类型
    • 提取 Promise 内的类型
    • 提取数组元素类型
    • 内置工具类型中的应用(ReturnTypeParameters 等)
  • 实战:封装工具类型
    • UnpackPromise<T>
    • First<T>Last<T>
    • ElementType<T>
  • 进阶技巧:多层 infer、递归推断
  • 总结与学习建议

1. 什么是 infer

infer 是 TypeScript 在条件类型(Conditional Types)中的关键字。

它的作用是:在类型推导过程中,声明一个待推断的类型变量

一句话理解:infer 就是“让 TS 在这里自动推断类型,并把它存下来(绑定成一个类型变量)”。


2. 基础用法:在条件类型中推断类型

最简单的形式:

type Foo<T> = T extends Array<infer U> ? U : T;

解释:

  • 如果 T 是数组(Array<...>),就提取里面的元素类型 U
  • 否则返回 T 本身

示例:

type A = Foo<string[]>; // string
type B = Foo<number>; // number

3. 常见场景与示例

3.1 提取函数返回值类型

type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function add(a: number, b: number) {
  return a + b;
}

type R = MyReturnType<typeof add>; // number

3.2 提取参数类型

type MyParameters<T> = T extends (...args: infer P) => any ? P : never;

function greet(name: string, age: number) {}

type Params = MyParameters<typeof greet>; // [string, number]

3.3 提取 Promise 内的类型

type UnpackPromise<T> = T extends Promise<infer U> ? U : T;

async function fetchUser() {
  return { id: 1, name: "Alice" };
}

type User = UnpackPromise<ReturnType<typeof fetchUser>>;
// { id: number; name: string }

3.4 提取数组元素类型

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

type E1 = ElementType<string[]>; // string
type E2 = ElementType<number[]>; // number

4. 内置工具类型中的应用

其实 TS 内置很多工具类型就是用 infer 实现的(思想一致,写法略有差异):

type ReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;

type Parameters<T extends (...args: any) => any> = T extends (
  ...args: infer P
) => any
  ? P
  : never;

举例:

function hello(a: string, b: number) {
  return true;
}

type R = ReturnType<typeof hello>; // boolean
type P = Parameters<typeof hello>; // [string, number]

5. 实战:封装工具类型

5.1 UnpackPromise<T>

提取 Promise 内的类型:

type UnpackPromise<T> = T extends Promise<infer U> ? U : T;

const p: Promise<string> = Promise.resolve("hi");
type R = UnpackPromise<typeof p>; // string

5.2 First<T>(数组第一个元素)

type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never;

type F1 = First<[1, 2, 3]>; // 1
type F2 = First<[]>; // never

5.3 Last<T>(数组最后一个元素)

type Last<T extends any[]> = T extends [...any[], infer L] ? L : never;

type L1 = Last<[1, 2, 3]>; // 3
type L2 = Last<[]>; // never

5.4 ElementType<T>(提取数组元素)

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

type E = ElementType<[string, number]>; // string | number

6. 进阶技巧:多层 infer、递归推断

6.1 多层 infer

可以在嵌套条件类型中多次使用 infer

type DeepUnpack<T> = T extends Promise<infer U>
  ? U extends Promise<infer K>
    ? K
    : U
  : T;

type X = DeepUnpack<Promise<Promise<number>>>; // number

6.2 递归推断

甚至可以递归定义,直到“解包到底”为止:

type DeepUnpackAll<T> = T extends Promise<infer U> ? DeepUnpackAll<U> : T;

type Y = DeepUnpackAll<Promise<Promise<Promise<string>>>>; // string

7. 总结与学习建议

  • infer 必须出现在条件类型
  • 它的主要作用是:临时声明一个类型变量,捕获 TS 推断出来的类型
  • 常见应用场景:提取函数参数/返回值、解包 Promise、提取数组元素类型

学习建议:

  • 先熟练掌握条件类型 T extends U ? X : Y 的匹配规则
  • 多看内置工具类型(ReturnTypeParameters 等)的实现思路
  • 练习从“模式匹配”的角度写类型:把目标类型拆成可匹配的结构,再用 infer 抽出你要的那部分

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...