编程TypeScript/全栈开发者

条件类型如何与 TypeScript 中的 infer 一起工作,它们在何种情况下是必要的,以及在实践中会遇到哪些错误?

用 Hintsage AI 助手通过面试

答案。

使用关键字 infer 的条件类型可以从复杂数据类型中提取类型。经典示例是从数组中提取元素类型:

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

在这里,infer U 允许 计算 数组 T 的元素类型。如果 T 是数组,将返回其元素的类型,否则返回 T 本身。

使用场合:

  • 编写通用的辅助类型(例如,从函数中提取返回类型、Promise 的值类型等)。

示例:

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

带陷阱的问题。

可以在一个条件类型中使用多个 infer 吗?TypeScript 如何解释这种情况?

错误答案:

  • "不能使用多个 infer,TypeScript 不允许这样做。"

正确答案:

  • 可以在一个模板中使用多个 infer 变量。例如,解析元组:
type FirstArgument<T> = T extends (infer F, ...any[]) => any ? F : never; // 但对于函数来说更准确: type Args<T> = T extends (...args: infer A) => any ? A : never;
  • TypeScript 正确地通过不同的 infer 变量推导多个类型。

由于对主题细节缺乏了解而导致的实际错误示例。


故事

开发者编写了获取函数返回对象类型的方法,但没有考虑到函数可能返回 Promise。结果,返回值的类型总是 Promise<any>,因为没有使用嵌套的条件与 extract/infer。不得不对整个代码库进行重构。


故事

在项目中引入了用于拆包嵌套数组的通用类型,但忘记在条件中写终止的 else-branch。TypeScript 没有正确报错,但在某些情况下使用时结果是 never,导致某些外部库的工具类型失败。


故事

同事试图通过 combine-conditional/infer 类型提取一个大接口的属性类型,但没有考虑到一些属性本身是 union 类型。结果输出了意外的 union 类型组合,编译器没有报错,但逻辑运行不正确。