TypeScript中回调函数参数赋值方向为何与普通函数相反?
为什么回调函数的参数赋值方向与普通函数相反?
这本质是TypeScript中函数参数的类型兼容性遵循逆变规则,核心目的是保证类型安全,我们结合你的例子拆解来看:
普通函数的赋值逻辑
普通函数调用时,是你作为调用者决定传递什么实参。比如:
const foo = (bar: string | number) => { console.log(bar); } foo('bar');
你传的'bar'是string的子类型(更窄),完全符合形参string | number的要求——形参能接收所有实参的可能值,不会出现类型不匹配的问题,所以这种赋值是安全的。
回调函数的特殊之处
回调函数的调用主体不是你,而是接收回调的函数(比如例子里的foo)。foo声明回调的参数类型是string | number,意味着它会向回调传递string或number类型的值。
如果你的回调函数bar只接受string类型参数:
const bar = (baz: string) => {}
当foo调用bar(42)(合法的number类型)时,bar的参数baz会接收到一个number值,但它的类型声明是string,这就直接违反了类型安全——bar无法处理number类型的输入。
所以TypeScript会检查:调用方传递的参数类型(string | number)必须能赋值给回调的参数类型。只有这样,回调才能处理调用方传来的所有合法值。在你的例子里,string | number不能赋值给string(因为number不属于string的范围),所以报错。
换个角度说:回调函数的参数类型必须是调用方声明的参数类型的超类型(更宽),才能覆盖所有可能的输入。比如如果你的回调参数是string | number或者any,就不会报错,因为它们能接收foo传递的任何值。
内容的提问来源于stack exchange,提问作者Magnus
相关产品推荐
相关产品推荐

