You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么TypeScript中Parameters可推断泛型参数但infer不行?

问题根因

你遇到的差异本质是TypeScript对逆变位点的infer推断规则与元组类型推断规则的不同:

  1. 你定义的Filter<T>接口中,泛型参数T处于函数参数位置,属于逆变位点。在TS 4.7之前,逆变位点的无修饰infer T会默认返回该位点的上界(无显式约束时上界为unknown),无法正确推导实际的参数类型;而TS 4.7之后默认对infer使用协变推断规则,逆变位点不加修饰符也会返回不符合预期的unknown。
  2. 内置工具类型Parameters的实现是直接推断函数的剩余参数元组infer P,元组类型的推断不受单类型逆变/协变规则影响,因此可以正确拿到实际参数类型。

解决方案

方案1:使用infer逆变修饰符(TS 4.7+ 推荐)

TS 4.7引入了infer的方差修饰符,在逆变位点做推断时加上in关键字即可正确推导参数类型,完全满足你希望用infer做自定义类型提取的需求,修改后代码如下:

// 给逆变位置的infer加上in修饰符
type InpInfer<F extends Filter<never>> = F extends Filter<infer in T> ? T : never;

修改后wrapInfer函数会正常编译,不会报类型不兼容错误,且推导出来的T类型为实际入参类型,无特殊指定时默认为unknown,符合你做类型交叉的要求。

方案2:自定义参数提取工具类型(兼容低版本TS)

如果需要兼容TS 4.7以下版本,可以自己实现和Parameters行为一致的提取类型,直接对函数调用签名做参数推断,避开逆变位点的单独infer:

type ExtractFilterParam<F extends Filter<never>> = F extends (inp: infer T) => boolean ? T : never;

该方案同样可以正确提取参数类型,推导结果和Parameters完全一致。

类型范围问题修复

你观察到的Parameters返回undefined属于未指定泛型具体类型时的默认推断行为,只要给泛型添加默认约束即可解决:

// 给F添加默认类型,未指定时参数类型为unknown
function wrapInfer<F extends Filter<never> = Filter<unknown>>(filt: F): Filter<InpInfer<F>> {
  const wrapper = (inp: InpInfer<F>): boolean => filt(inp);
  return wrapper;
}

修改后未指定具体Filter类型时,默认的参数类型为unknown,unknown & T的类型运算结果符合预期,不会出现never的问题。


内容的提问来源于stack exchange,提问作者Erik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 14:06:05