infer 是 TypeScript 中用于在条件类型中延迟推导类型的关键字,必须出现在 extends 右侧,通过匹配结构提取类型并绑定到类型变量,如 ReturnType、InstanceType 等均依赖其实现类型提取与解包。

infer 是 TypeScript 中用于在条件类型中**延迟推导类型**的关键字,它本身不能独立使用,必须出现在 extends 子句的右侧(即条件类型的“检查部分”),配合 extends 实现类型提取。它的核心作用是:当 TypeScript 在类型层面“匹配”某个结构时,让编译器把匹配到的某一部分“记下来”,并赋予一个类型变量名,供后续使用。
infer 的基本用法:从函数类型中提取返回值类型
这是最经典、最直观的例子:
type ReturnType这里:
-
T extends (...args: any[]) => infer R表示:如果类型T能被匹配为“一个函数类型”,那么就把它的返回值类型“推导出来”,记作R; -
infer R不是声明变量,而是告诉编译器:“请在这里尝试提取一个类型,并叫它R”; - 匹配成功后,
R就代表该函数的实际返回类型,于是整个条件类型的结果就是R; - 如果
T不是函数类型,就不满足extends条件,结果回退到never。
使用示例:
type A = ReturnType string>; // stringtype B = ReturnType
infer 提取泛型参数:从构造函数或实例类型中拿 T
常见需求:已知一个类构造函数类型 new () => T,想拿到里面的 T(即实例类型)。
再比如,想从 Promise 中提取 T:
这样就能层层解包:
type X = UnwrapPromisetype Y = UnwrapPromise
infer 可多次出现,也可嵌套使用
一个条件类型中可以有多个 infer,只要它们出现在不同位置且逻辑可推导:
甚至可以组合使用,例如同时提取参数和返回值:
type FuncParts? { args: A; return: R }
: never;
调用 FuncParts boolean> 得到:{ args: [number, string]; return: boolean }。
注意事项与常见误区
-
infer只在条件类型(T extends U ? X : Y)中合法,写在普通类型别名或接口里会报错; - 不能在非分布式的上下文中“跨分支”引用同一个
infer类型变量(例如在else分支里用R); - 推导结果可能为联合类型:若
T是多个函数的联合,infer R会得到对应返回类型的联合; - 避免过度嵌套条件类型,容易导致编译器性能下降或推导失败;
- 推荐搭配
type别名封装,提升可读性和复用性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











