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

TypeScript交叉类型场景下条件类型推断结果过宽问题如何解决

问题原因

这个问题是TypeScript类型系统的两个特性共同导致的:

  1. 交叉类型的重载合并规则:交叉类型合并方法时,会把右侧类型的方法重载排在左侧类型的重载前面。你的DynamicListBuilder是ListBuilder和新增重载类型的交叉,所以合并后的add方法重载,新增的两个双参数重载会排在原有三个重载的前面。
  2. 重载函数的类型兼容性规则:TypeScript在判断重载函数的类型兼容性、以及做infer推断时,会优先匹配靠前的重载,同时函数参数处于逆变位置,且允许少传参数调用。匹配ListBuilder<infer TItem>的add方法时,靠前的新增重载会被纳入推断范围:
    • 新增的双参数重载可以被当成单参数函数使用(符合JS少传参数的语法规则),第一个参数的字面量类型'itemFactory'、'listFactory'、原有重载里的'list'都会被推断为TItem的候选
    • 匹配双参数重载时,新增重载的第二个参数的函数类型() => number也会被纳入TItem的候选
    • 同时get方法返回的number[]是协变位置,允许number是TItem的子类型
      最终TItem就被推断为所有候选类型的联合number | "list" | (() => number)。

解决方法

不要从有重载的逆变位置(add方法)推断泛型,直接从无重载的协变位置(get方法)提取类型即可,调整后的ItemFor如下:

type ItemFor<TListBuilder> = TListBuilder extends { get(): infer TItem[] } ? TItem : never;

调整后Inferred类型会正确推断为number,不符合预期的赋值和方法调用也会正常报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:48:02