TypeScript 中的 infer 关键字详解 🔍

153 阅读2分钟

什么是 infer? 🤔

inferTypeScript中的一个关键字,它可以在条件类型中推断类型变量。简单来说,它就是像一个占位符,用于从现有类型中提取类型信息。

基本语法 📝

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

🔍代码解析

  • (...args: any[])表示任意参数列表
  • infer R表示我们要推断的返回值类型
  • ? R : never 三元表达式结果

让我们通过几个例子来理解infer的使用

infer的实际应用🌟

1. 提取函数返回值类型

// 示例1:提取函数返回值类型
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function getMessage(): string {
    return "Hello World";
}
type MessageType = GetReturnType<typeof getMessage>; // string

2. 提取数组元素类型

// 示例2:提取数组元素类型
type GetArrayElement<T> = T extends Array<infer E> ? E : never;

type NumberArray = number[];
type ElementType = GetArrayElement<NumberArray>; // number

3. 提取Promise值类型

type GetPromiseType<T> = T extends Promise<infer P> ? P : never
type PromiseString = Promise<string>
type ResultType = GetPromiseType<PromiseString>

4. 提取函数参数类型

type GetParameterTypes<T> = T extends (...args: infer P) => any ? P : never;
function greet(name: string, age: number): void {}
type GreetParams = GetParameterTypes<typeof greet>; //  [name: string, age: number]

// 传入非函数的情况下会返回never
type GreetParams1 = GetParameterTypes<string>; // never
type GreetParams2 = GetParameterTypes<string>; // never
type GreetParams3 = GetParameterTypes<null>; // never

理解 infer 的工作原理🧩

  1. 它只能在extends条件类型中使用
  2. 它会根据实际类型自动推断出对应的类型
  3. 推断出的类型可以在条件类型的true分支中使用

使用注意事项 ⚠️

  1. infer 只能在 extends 条件类型中使用
  2. 同一个类型参数可以使用多个 infer
  3. infer 推断的类型变量只能在 true 分支中使用

实践练习 💡

// 练习:提取元组的第一个元素类型
type GetFirst<T> = T extends [infer First, ...any[]] ? First : never;
type FirstElement = GetFirst<[string, number, boolean]>; // string

// 练习:提取函数的最后一个参数类型
type GetLastParameter<T> = T extends (...args: [...infer Rest, infer Last]) => any ? Last : never;
function example(a: string, b: number, c: boolean, d: 123) {}
type LastParam = GetLastParameter<typeof example>; // boolean

总结 📝

infer 是 TypeScript 中非常强大的类型推断工具:

  • 用于在条件类型中提取类型信息
  • 可以提取函数返回值、参数、构造函数等类型