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

条件类型不健全性:何时X=>string会与any=>string被统一?

TypeScript条件类型不健全性示例解析

先明确核心问题:TypeScript的条件类型统一算法在处理逆变位置的类型参数时,会错误地将泛型参数X拓宽为any,导致(x: X) => string与(x: any) => string被判定为兼容,进而引发运行时错误。

逆变位置的基本规则

函数的参数类型属于逆变位置:若A extends B,则(x: B) => void extends (x: A) => void。简单说,接受更宽泛参数的函数可以替代接受更窄参数的函数,反之则不行。比如(x: any) => string可以赋值给(x: number) => string(因为any能包含number),但(x: number) => string绝对不能赋值给(x: any) => string(传入非number会报错)。

错误统一的示例

1. 条件类型判断错误

type IsCompatible<X> = ((x: X) => string) extends ((x: any) => string) ? true : false;

// 预期:IsCompatible<number>应为false(因为number函数不能接受any参数)
// 实际:TypeScript返回true,算法错误将X拓宽为any
type TestNumber = IsCompatible<number>; // true
type TestString = IsCompatible<string>; // true

这里TypeScript错误认为任意(x: X) => string都兼容(x: any) => string,完全违背了逆变规则。

2. 运行时错误场景

基于上面的错误判断,TypeScript会允许不安全的函数赋值,最终导致运行时崩溃:

function unsafeAssign<X>(fn: (x: X) => string): (x: any) => string {
  return fn; // TypeScript认为这个赋值合法,但实际不安全
}

// 定义一个仅接受number的函数
const numToFixed = (x: number) => x.toFixed(2);

// 错误地获得一个声称接受any的函数
const anyToFixed = unsafeAssign(numToFixed);

// 运行时错误:传入字符串调用,x.toFixed不存在
anyToFixed("hello"); // Uncaught TypeError: x.toFixed is not a function

为什么你的测试代码表现正常

你测试的type Test<X> = ((x:X) => string) extends ((x:number) => string) ? true : false符合逆变规则:

  • 当X extends number时,(x: number) => string extends (x: X) => string,所以Test<X>返回true(比如Test<number>为true);
  • 当X是其他类型(如string),(x:string) => string不extends (x:number) => string,返回false。
    这个场景中没有涉及any的错误拓宽,所以结果符合预期。

内容的提问来源于stack exchange,提问作者Andrea Simone Costa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:50:38