为啥函数重载不提示错误?

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 
  // ...

【讨论】:

这如何工作?函数反向(x: T): T 返回 1 + x;错误消息是“运算符'+'不能应用于类型'number'和'T'” 在我看来你属于这种情况:***.com/questions/54470329/… 另见***.com/questions/57686313/…

以上是关于为啥函数重载不提示错误?的主要内容,如果未能解决你的问题,请参考以下文章

在重载时为啥不考虑函数的返回类型? [复制]

为啥不允许“重载函数的第二个 C 链接”?

为啥具有相同名称但不同签名的多个继承函数不会被视为重载函数?

为啥 const/non-const 函数重载的继承不明确?

为啥在析构函数中抛出异常时不调用重载删除?

为啥我不能在 PHP 中重载构造函数?