为啥函数重载不提示错误?
Posted
技术标签:
【中文标题】为啥函数重载不提示错误?【英文标题】:Why does function overloading not prompt an error?为什么函数重载不提示错误? 【发布时间】:2021-12-19 05:52:35 【问题描述】:function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string
return x + '1';
为什么 typescript 可以使用这个函数重载? 我想限制数字输入数字输出和字符串输入字符串输出。
在我的函数实现中,我故意让数字输入字符串输出。而且我希望在编译这个 ts 文件时会抛出一条错误消息,但它没有。为什么?
环境:没有 tsconfig.json 和 tsc 版本是 4.4.3
【问题讨论】:
【参考方案1】:Typescript 并不完美。查看Github issue #13235 了解有关此特定缺陷的更多信息。
基本上,您的实现函数不知道存在重载签名。它被输入返回string | number
,它返回string
,这是一个完全有效的返回类型。就是这么简单。
是的,在这种情况下,即使代码编译没有错误,您也可能在运行时遇到类型错误。这是一个盲点,没有好的方法可以覆盖。
为什么它不完美?好吧,从那个 Github 问题中,这句话更能说明问题。
似乎没有太多证据表明人们在这里经常犯错误,我们可以可靠地检测到而不会引入误报。但真正的问题是,这里的任何实现都将至少在签名数量上为 O(n^2),并且有许多 .d.ts 文件,每个函数实际上有几十个签名。每次开始时错误非常少时检查重载中“正确性”的成本和复杂性似乎并不值得。
【讨论】:
感谢您提供如此详细的信息。我想我现在可以接受这种不完美了。【参考方案2】:FWIW,在您的情况下,您可能更愿意使用泛型。
您希望输出类型取决于输入类型:
function reverse<T extends string | number>(x: T): T
// ...
【讨论】:
这如何工作?函数反向以上是关于为啥函数重载不提示错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥具有相同名称但不同签名的多个继承函数不会被视为重载函数?