为什么TypeScript中传入不符合类型定义的回调未触发编译错误?
原因说明
1. 返回值为void的特殊校验规则
TypeScript 中对返回值标注为 void 的函数类型有特殊兼容设计:不会要求传入的函数实际返回空值,只是会自动忽略传入函数的返回值。
这个设计是为了适配大量通用回调场景,比如数组forEach、DOM事件绑定的回调,它们的回调类型定义都是返回void,但实际开发中我们经常会传入有返回值的函数(比如arr.forEach(item => list.push(item)),push方法返回的是数组长度,属于number类型),如果严格校验返回值反而会增加不必要的报错。
你这里传入的b函数返回number类型,刚好符合这个兼容规则,所以不会触发错误。
2. 函数参数数量的兼容规则
TypeScript 做函数类型匹配时,允许传入参数数量少于定义要求的函数。你定义的fn要求接收1个string类型参数,传入的b是无参函数,调用时a内部传给fn的字符串会被b直接忽略,不会引发运行时异常,因此 TS 也允许这种兼容行为。
3. 内部调用fn传参报错的原因
你修改fn调用参数为123时触发错误,是因为fn的类型明确要求入参为string,调用方传入不符合类型要求的参数自然会触发校验,这和上面提到的回调传入时的兼容规则属于不同的校验场景,互不冲突。
验证方式
如果需要严格校验回调的返回值,把fn的返回值类型从void改成undefined即可,此时传入返回1的b函数就会触发类型错误:
function a(fn: (a: string) => undefined) { fn("Hello, World"); }
如果传入的回调参数类型不匹配(比如b要求接收number类型参数),同样会触发错误:
a(function b(n: number) { return 1 })
内容的提问来源于stack exchange,提问作者Chor
相关产品推荐
相关产品推荐

