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

TypeScript非严格模式下函数类型异常赋值无报错问题咨询

关于TypeScript非严格模式下函数赋值校验的问题说明

核心结论

你碰到的v4: expectB = testA 不报错,既不是你代码写错了,也不是TS的类型校验完全失效——本质是两个点叠加的结果:

  1. 这个赋值场景本身就是类型安全的,哪怕开最严的校验规则,也本来就不该报错
  2. 非严格模式真正放宽校验、存在安全隐患的地方,恰恰是你注释里标为「正常」的v2: expectA = testB

非严格模式的函数校验逻辑

没开严格模式时,TS对函数类型的参数兼容判定默认是 双变规则:

  • 只要源函数和目标函数的参数类型存在继承关联,就允许跨类型赋值,不强制做严格的参数类型匹配
  • 等你开了strictFunctionTypes: true(严格模式自带的开关)之后,函数参数会切到严格逆变校验,专门拦那些不安全的赋值场景

逐行对应你的代码分析

判断函数赋值是否安全的核心标准非常简单:把源函数绑给目标变量之后,后续调用目标变量时传的参数,能不能被源函数正常处理。按这个标准逐行看:

  • v1: expectA = testA
    两个函数的参数类型完全一致,不管什么校验规则都能过,属于完全正常的场景
  • v2: expectA = testB
    目标变量v2的类型是“收A类型参数的函数”,后续调用v2的时候,你完全可以传一个只有f1方法的纯A对象进去;但源函数testB要求参数必须带f2方法,真传个纯A过去,运行时访问f2直接就崩了——这才是真正有安全隐患的赋值。
    非严格模式下因为双变规则觉得A和B是继承关系,就直接放行了这个操作;切到严格模式时,这行代码会直接抛TS2322错误。
  • v3: expectA = testC
    C和A没有任何继承关联,没有任何兼容通路,不管哪种模式都会报错,完全符合你的预期
  • v4: expectB = testA
    目标变量v4的类型是“收B类型参数的函数”,后续调用v4的时候,传进来的一定是同时带f1/f2方法的B类型对象;而源函数testA只要求参数有f1方法,B天生就有A的所有属性,传进去的参数testA完全能正常处理,这个赋值本来就是合法安全的——不管严格还是非严格模式,这行代码都不会报错。你觉得它是异常,其实是把参数兼容的方向搞反了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 18:45:03