使用关键字 infer 的条件类型可以从复杂数据类型中提取类型。经典示例是从数组中提取元素类型:
type ElementType<T> = T extends (infer U)[] ? U : T;
在这里,infer U 允许 计算 数组 T 的元素类型。如果 T 是数组,将返回其元素的类型,否则返回 T 本身。
使用场合:
示例:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
可以在一个条件类型中使用多个 infer 吗?TypeScript 如何解释这种情况?
错误答案:
正确答案:
type FirstArgument<T> = T extends (infer F, ...any[]) => any ? F : never; // 但对于函数来说更准确: type Args<T> = T extends (...args: infer A) => any ? A : never;
故事
开发者编写了获取函数返回对象类型的方法,但没有考虑到函数可能返回 Promise。结果,返回值的类型总是 Promise<any>,因为没有使用嵌套的条件与 extract/infer。不得不对整个代码库进行重构。
故事
在项目中引入了用于拆包嵌套数组的通用类型,但忘记在条件中写终止的 else-branch。TypeScript 没有正确报错,但在某些情况下使用时结果是 never,导致某些外部库的工具类型失败。
故事
同事试图通过 combine-conditional/infer 类型提取一个大接口的属性类型,但没有考虑到一些属性本身是 union 类型。结果输出了意外的 union 类型组合,编译器没有报错,但逻辑运行不正确。