TypeScript非严格模式下函数类型异常赋值无报错问题咨询
关于TypeScript非严格模式下函数赋值校验的问题说明
核心结论
你碰到的v4: expectB = testA 不报错,既不是你代码写错了,也不是TS的类型校验完全失效——本质是两个点叠加的结果:
- 这个赋值场景本身就是类型安全的,哪怕开最严的校验规则,也本来就不该报错
- 非严格模式真正放宽校验、存在安全隐患的地方,恰恰是你注释里标为「正常」的
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
相关产品推荐
相关产品推荐

