有没有人在TypeScript中完成构造函数重载 . 在语言规范的第64页(v 0.8)上,有一些描述构造函数重载的语句,但是没有给出任何示例代码 .
我现在正在尝试一个非常基本的课堂宣言;它看起来像这样,
interface IBox {
x : number;
y : number;
height : number;
width : number;
}
class Box {
public x: number;
public y: number;
public height: number;
public width: number;
constructor(obj: IBox) {
this.x = obj.x;
this.y = obj.y;
this.height = obj.height;
this.width = obj.width;
}
constructor() {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
}
}
当使用tsc BoxSample.ts运行时,它会抛出一个重复的构造函数定义 - 这很明显 . 任何帮助表示赞赏 .
10 回答
你应该记住......
它与
new()
或new("a","b","c")
相同从而
是同样的,更灵活......
new()
或new("a")
或new("a","b")
或new("a","b","c")
TypeScript允许您声明重载,但是您只能有一个实现,并且该实现必须具有与所有重载兼容的签名 . 在您的示例中,可以使用可选参数轻松完成此操作,如
或两个带有更通用构造函数的重载,如
请注意,您还可以通过TypeScript中的默认参数解决实现级别的重载缺失问题,例如:
编辑:自2016年12月5日起,请参阅Benson's answer以获得更精细的解决方案,从而提供更大的灵活性 .
关于 constructor overloads ,一种替代方案是将额外的重载实现为 static factory methods . 我认为它比测试你的调用参数更具可读性和更少混淆 . 这是一个简单的例子:
TypeScript中的方法重载不是真的,让's say, as it would require too much compiler-generated code and the core team try to avoid that at all costs. Currently the main reason for method overloading to be present on the language is to provide a way to write declarations for libraries with magic arguments in their API. Since you' ll需要自己完成所有繁重工作以处理不同的参数集我在使用重载而不是分离的方法时看不到多少优势 .
注意:这已经过简化并在4/13/2017更新以反映TypeScript 2.1,请参阅TypeScript 1.8答案的历史记录 .
听起来您希望object参数是可选的,并且对象中的每个属性都是可选的 . 在示例中,如提供的那样,重载语法isn 't needed. I wanted to point out some bad practices in the some of the answers here. Granted, it'不是本质上写入
box = { x: 0, y: 87, width: 4, height: 0 }
的最小可能表达式,但是这提供了所有可能想要从类中描述的细节的代码 . 此示例允许您使用一个,一些,全部或没有参数调用函数,并仍然获取默认值 .这是一种非常安全的方法来编写可能没有定义对象的所有属性的参数 . 您现在可以安全地编写以下任何内容:
编译后,你会发现可选参数确实是可选的,通过检查
void 0
(这是undefined
的简写)避免了var = isOptional || default;
广泛使用(但容易出错)的回退语法的缺陷:编译输出
附录:设置默认值:错误的方式
|| (或)运营商
在设置默认回退值时,请考虑
||
/或运算符的危险,如其他一些答案所示 . 下面的代码说明了设置默认值的错误方法 . 在评估0,',null,undefined,false,NaN等假值时,可能会得到意外结果:Object.assign(this,obj)
在我的测试中,使用es6 / typescript destructured object can be almost 90% faster than Object.assign . 使用destructured参数只允许您为对象分配的方法和属性 . 例如,考虑这种方法:
如果其他用户不属于,那么他们可能会尝试使用
z
属性我知道这是一个老问题,但1.4中的新内容是联合类型;将这些用于所有函数重载(包括构造函数) . 例:
Update (8 June 2017): guyarad和snolflake在下面的评论中给出了有效的答案 . 我建议读者查看Benson,Joe和snolflake的答案,他们的答案比我的答案要好 .
Original Answer (27 January 2014)
另一个如何实现构造函数重载的例子:
资料来源:http://mimosite.com/blog/post/2013/04/08/Overloading-in-TypeScript
在可选的类型化参数足够好的情况下,请考虑以下代码,这些代码在不重复属性或定义接口的情况下完成相同的操作:
请记住,如果未在
Track
上定义,则将分配在track
中传递的所有属性 .另一个版本喜欢@ ShinNoNoir的代码,使用默认值和扩展语法:
您可以通过以下方式处理:
部分将使您的字段(x,y,height,width)可选,允许多个构造函数
例如:你可以做没有高度和宽度的
new Box({x,y})
.= {}
将处理假值,如undefined,null等,然后你可以做new Box()