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

TypeScript实现联合类型判断泛型时推导异常的解决方案

问题根因

初始代码结果不符合预期,本质是触发了TypeScript条件类型的分布式行为:
当extends前的泛型参数是「裸类型」(没有被元组、数组等类型包装)时,传入联合类型会被自动拆解,对每个成员单独做条件判断,最后把所有结果合并为联合类型返回。

以Selector<string | number>为例,实际计算过程是:

  1. 联合类型被拆为string和number两个独立类型
  2. 分别计算:string extends string得到'string',number extends string得到'primitive'
  3. 结果合并为'string' | 'primitive',和预期的'primitive'不一致。

实现方案

要满足需求需要做两处修正:

  1. 用元组包裹extends两侧的类型,取消分布式判断,让TypeScript对整个联合类型做整体兼容性检查,而不是拆分判断
  2. 增加一层类型判断区分「字符串字面量联合」和「宽泛的string原始类型」:对于字符串字面量类型T,string extends T永远不成立;只有当T是宽泛的string类型时,这个判断才成立。

最终可运行的代码如下:

type PrimitiveDataType = 'primitive';
type StringValue = 'string';

type Selector<T> = [T] extends [string]
  ? string extends T
    ? PrimitiveDataType
    : StringValue
  : PrimitiveDataType;

// 用例验证
type StringCheck = Selector<'boo' | 'bar'>; // 推导出'string',符合预期
type PrimitiveCheck = Selector<string | number>; // 推导出'primitive',符合预期

边界场景覆盖

这个实现同时可以覆盖所有符合需求描述的边界情况:

  • 单个字符串字面量:Selector<'abc'>返回'string'
  • 宽泛string原始类型:Selector<string>返回'primitive'
  • 非字符串原始类型联合:Selector<number | boolean>返回'primitive'
  • 字符串字面量与宽泛string混合:Selector<'abc' | string>返回'primitive'

内容的提问来源于stack exchange,提问作者cyrus-d

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:48:29