有人在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,它抛出一个重复的构造函数定义——这是显而易见的。任何帮助都是感激的。


当前回答

更新2(2020年9月28日):这种语言在不断发展,所以如果你可以使用Partial(在v2.1中引入),那么这是我现在最喜欢的实现这一目标的方式。

class Box {
   x: number;
   y: number;
   height: number;
   width: number;

   public constructor(b: Partial<Box> = {}) {
      Object.assign(this, b);
   }
}

// Example use
const a = new Box();
const b = new Box({x: 10, height: 99});
const c = new Box({foo: 10});          // Will fail to compile

更新(2017年6月8日):guyarad和snolflake在他们的评论中对我的回答提出了有效的观点。我建议读者看看Benson, Joe和snolflake的答案,他们的答案比我的更好

原答案(2014年1月27日)

另一个如何实现构造函数重载的例子:

class DateHour {

  private date: Date;
  private relativeHour: number;

  constructor(year: number, month: number, day: number, relativeHour: number);
  constructor(date: Date, relativeHour: number);
  constructor(dateOrYear: any, monthOrRelativeHour: number, day?: number, relativeHour?: number) {
    if (typeof dateOrYear === "number") {
      this.date = new Date(dateOrYear, monthOrRelativeHour, day);
      this.relativeHour = relativeHour;
    } else {
      var date = <Date> dateOrYear;
      this.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
      this.relativeHour = monthOrRelativeHour;
    }
  }
}

来源:http://mimosite.com/blog/post/2013/04/08/Overloading-in-TypeScript

其他回答

在可选的类型参数足够好的情况下,考虑以下代码,它可以在不重复属性或定义接口的情况下实现相同的功能:

export class Track {
   public title: string;
   public artist: string;
   public lyrics: string;

   constructor(track?: Track) {
     Object.assign(this, track);
   }
}

请记住,这将分配所有传递到track的属性,即使它们没有在track上定义。

更新2(2020年9月28日):这种语言在不断发展,所以如果你可以使用Partial(在v2.1中引入),那么这是我现在最喜欢的实现这一目标的方式。

class Box {
   x: number;
   y: number;
   height: number;
   width: number;

   public constructor(b: Partial<Box> = {}) {
      Object.assign(this, b);
   }
}

// Example use
const a = new Box();
const b = new Box({x: 10, height: 99});
const c = new Box({foo: 10});          // Will fail to compile

更新(2017年6月8日):guyarad和snolflake在他们的评论中对我的回答提出了有效的观点。我建议读者看看Benson, Joe和snolflake的答案,他们的答案比我的更好

原答案(2014年1月27日)

另一个如何实现构造函数重载的例子:

class DateHour {

  private date: Date;
  private relativeHour: number;

  constructor(year: number, month: number, day: number, relativeHour: number);
  constructor(date: Date, relativeHour: number);
  constructor(dateOrYear: any, monthOrRelativeHour: number, day?: number, relativeHour?: number) {
    if (typeof dateOrYear === "number") {
      this.date = new Date(dateOrYear, monthOrRelativeHour, day);
      this.relativeHour = relativeHour;
    } else {
      var date = <Date> dateOrYear;
      this.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
      this.relativeHour = monthOrRelativeHour;
    }
  }
}

来源:http://mimosite.com/blog/post/2013/04/08/Overloading-in-TypeScript

你应该记住……

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”)

我使用以下替代方法来获得默认/可选参数和“kind-of-overloaded”的构造函数,参数数量可变:

private x?: number;
private y?: number;

constructor({x = 10, y}: {x?: number, y?: number}) {
 this.x = x;
 this.y = y;
}

我知道这不是最漂亮的代码,但人们会习惯它。不需要额外的接口,它允许私有成员,这在使用接口时是不可能的。

我知道这是一个老问题,但1.4中的新功能是联合类型;对所有函数重载(包括构造函数)使用这些。例子:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);