为啥 TypeScript 中没有重载的构造函数实现?

Posted

技术标签:

【中文标题】为啥 TypeScript 中没有重载的构造函数实现?【英文标题】:Why no overloaded constructor implementations in TypeScript?为什么 TypeScript 中没有重载的构造函数实现? 【发布时间】:2017-01-11 10:00:07 【问题描述】:

在 TypeScript 中,只能重载构造函数类型签名,而不能重载实现。这背后有什么原因吗?我认为像 Java 这样的重载构造函数非常有用。例如,向量的定义可以是结束坐标,或者起点和终点,或者两个向量等等。 目前 TypeScript 中的方法非常混乱。那么为什么打字稿没有呢?

【问题讨论】:

你得问问语言设计者,其他人只能推测。见a similar case。 @torazaburo typescript 不仅仅是一个预处理器。查看编译器的代码,它与其说是预处理器,不如说是一种发出 javascript 的语言(这是 javascript VM 的“字节码”。如果有任何较低级别的东西,它可以发出)。它的实现方式与许多其他编程语言一样。 @torazaburo Javascript 已经完成,打字稿可以模拟任何东西。他们选择是完全不同的事情。 @torazaburo 我们不要在这里混合我们的苹果和橙子。当然 TS 不能改变底层语言的性质,但它们可以模拟任何更高级别的功能,例如适当的过载。但他们不想这样做,因为让 TS 接近 JS 是一个明确的目标。 @SimonMeskens 不一定,TS 可以作为开始在构造函数/合并函数中插入逻辑,检查参数的数量,然后相应地执行特定的逻辑。然后我们至少根据参数计数有更好的重载。而且我敢肯定,如果我们正确地为编译器提供相关的自定义类型保护,我们甚至可以进行一些类型检查。我并不是说它总是简单而高效,但没有什么是不可能的。 【参考方案1】:

是的,这是有原因的,原因是javascript不支持对方法或成员使用相同的名称。

考虑以下打字稿:

class MyClass 
    myMethod() 
    myMethod(str: string) 

编译后的版本是:

var MyClass = (function () 
    function MyClass() 
    
    MyClass.prototype.myMethod = function ()  ;
    MyClass.prototype.myMethod = function (str)  ;
    return MyClass;
());

如您所见,myMethod 的第二个实现正在替换第一个实现。 因此,您只能重载签名,然后您需要提供满足所有声明签名的单个实现。

【讨论】:

2 个构造函数不会产生 2 个 MyClass 函数吗?而且由于 javascript 不支持多态性,第二个会覆盖第一个,因此不可能有 2 个构造函数。 @toskv 对,理论上 2 ctor 最终会成为第二个 MyClass 函数,它将覆盖第一个 . @NitzanTomer 这就是为什么它目前无法正常工作,但编译器是可变的,并且仅仅因为它当前编译如你所提到的并不意味着它可以被更改为编译为不同的 js 代码来实现某些东西并行的单个“真实”构造函数和辅助构造函数,它们表示重载的打字稿构造函数。 @Phosphoros 没错,除了很多其他的东西之外,它还可以添加到语言中,但是打字稿作为一种语言将与 javascript 相差太远,这违背了语言的哲学。 【参考方案2】:

我提交了issue,结果是:这在技术上是可行的,但会破坏设计目标。 感谢大家参与讨论。

【讨论】:

以上是关于为啥 TypeScript 中没有重载的构造函数实现?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中实现的接口中进行构造函数重载?

如何在 TypeScript 的派生类中进行构造函数重载?

TypeScript 类方法具有与构造函数相同的重载签名

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

TypeScript,面向对象,类、构造函数、继承、抽象类、接口和封装

为啥 Typescript 在转译代码中将 .default() 添加到类构造函数中?