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

TypeScript条件类型中联合类型被转为never的问题求助

TypeScript条件类型处理联合类型时参数变为never的问题解决

问题复现

定义了如下条件类型:

type SimpleTest<U> = U extends {something: string}
    ? () => void
    : (a: U) => U

当传入联合类型'test' | 'rest'时,出现不符合预期的类型错误:

function test(a: SimpleTest<'test' | 'rest'>) {
    a('test');     // 错误:TS2345: 类型“string”的参数不能赋给类型“never”的参数。
}

实际推导得到的类型是(a: never) => ("test" | "rest"),但期望的是(a: "test" | "rest") => ("test" | "rest")。

问题原因

这是TypeScript分布式条件类型的特性导致的:当泛型参数是「裸类型」(未被包裹在数组、对象等容器类型中)时,条件类型会自动遍历联合类型的每个成员,分别应用条件判断后再合并结果。

对SimpleTest<'test' | 'rest'>来说,实际执行逻辑是:

  • 拆分联合类型为'test'和'rest'两个独立成员
  • 对每个成员应用条件:两者都不满足{something: string},因此得到两个函数类型:(a: 'test') => 'test' 和 (a: 'rest') => 'rest'
  • 合并这两个函数类型:函数参数是逆变的,交叉后'test' & 'rest'等于never;返回值是协变的,合并后是'test' | 'rest',最终就得到了(a: never) => ("test" | "rest")。

解决方案

要阻止条件类型的自动分发,只需将泛型参数U包裹在一个非裸类型中(比如元组、对象),让条件判断针对整个联合类型而非单个成员:

type SimpleTest<U> = [U] extends [{something: string}]
    ? () => void
    : (a: U) => U

修改后,SimpleTest<'test' | 'rest'>会直接将整个联合类型'test' | 'rest'与{something: string}做判断,显然不满足条件,因此会返回(a: 'test' | 'rest') => 'test' | 'rest',此时调用a('test')就不会再报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:06:24