有人在TypeScript中做过构造函数重载吗?在语言规范(v 0.8)的第64页,有描述构造函数重载的语句,但没有给出任何示例代码。
我现在正在尝试一个非常基本的类声明;它是这样的,
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,它抛出一个重复的构造函数定义——这是显而易见的。任何帮助都是感激的。
TypeScript允许你声明重载,但是你只能有一个实现,而且这个实现必须有一个与所有重载兼容的签名。在你的例子中,这可以很容易地用一个可选参数来完成,
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 ?? 0
this.y = obj?.y ?? 0
this.height = obj?.height ?? 0
this.width = obj?.width ?? 0;
}
}
或者使用更通用的构造函数进行两次重载,
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();
constructor(obj: IBox);
constructor(obj?: IBox) {
this.x = obj?.x ?? 0
this.y = obj?.y ?? 0
this.height = obj?.height ?? 0
this.width = obj?.width ?? 0;
}
}
参见游乐场
你应该记住……
contructor()
constructor(a:any, b:any, c:any)
它和new()或者new("a","b","c")一样
Thus
constructor(a?:any, b?:any, c?:any)
和上面一样,而且更灵活…
新()或新的(“a”)或(“a”、“b”)或新(“a”、“b”、“c”)
Box类试图定义多个构造函数实现。
只有最后一个构造函数重载签名被用作类构造函数实现。
在下面的示例中,请注意构造函数实现的定义与前面的任何重载签名都不冲突。
interface IBox = {
x: number;
y: number;
width: number;
height: number;
}
class Box {
public x: number;
public y: number;
public width: number;
public height: number;
constructor() /* Overload Signature */
constructor(obj: IBox) /* Overload Signature */
constructor(obj?: IBox) /* Implementation Constructor */ {
if (obj) {
this.x = obj.x;
this.y = obj.y;
this.width = obj.width;
this.height = obj.height;
} else {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0
}
}
get frame(): string {
console.log(this.x, this.y, this.width, this.height);
}
}
new Box().frame; // 0 0 0 0
new Box({ x:10, y:10, width: 70, height: 120 }).frame; // 10 10 70 120
// You could also write the Box class like so;
class Box {
public x: number = 0;
public y: number = 0;
public width: number = 0;
public height: number = 0;
constructor() /* Overload Signature */
constructor(obj: IBox) /* Overload Signature */
constructor(obj?: IBox) /* Implementation Constructor */ {
if (obj) {
this.x = obj.x;
this.y = obj.y;
this.width = obj.width;
this.height = obj.height;
}
}
get frame(): string { ... }
}
注意,你也可以通过TypeScript中的默认参数来解决在实现级别上缺乏重载的问题,例如:
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 = {x:0,y:0, height:0, width:0}) {
this.x = obj.x;
this.y = obj.y;
this.height = obj.height;
this.width = obj.width;
}
}
编辑:
截至2016年12月5日,请参阅本森的回答,以获得更灵活的更详细的解决方案。