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


当前回答

你可以通过以下方法来处理:

class Box {
  x: number;
  y: number;
  height: number;
  width: number;
  constructor(obj?: Partial<Box>) {    
     assign(this, obj);
  }
}

Partial将使你的字段(x,y,高度,宽度)可选,允许多个构造函数

例如:你可以新建Box({x,y})没有高度和宽度。

其他回答

实际上,现在回答这个问题可能太晚了,但你现在可以这样做:

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

    constructor();
    constructor(obj: IBox);
    constructor(obj?: IBox) {    
        this.x = !obj ? 0 : obj.x;
        this.y = !obj ? 0 : obj.y;
        this.height = !obj ? 0 : obj.height;
        this.width = !obj ? 0 : obj.width;
    }
}

因此,你可以不使用静态方法,而是使用上述方法。希望能对你有所帮助!!

我们可以使用守卫来模拟构造函数重载

interface IUser {
  name: string;
  lastName: string;
}

interface IUserRaw {
  UserName: string;
  UserLastName: string;
}

function isUserRaw(user): user is IUserRaw {
  return !!(user.UserName && user.UserLastName);
}

class User {
  name: string;
  lastName: string;

  constructor(data: IUser | IUserRaw) {
    if (isUserRaw(data)) {
      this.name = data.UserName;
      this.lastName = data.UserLastName;
    } else {
      this.name = data.name;
      this.lastName = data.lastName;
    }
  }
}

const user  = new User({ name: "Jhon", lastName: "Doe" })
const user2 = new User({ UserName: "Jhon", UserLastName: "Doe" })

你应该记住……

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

下面是一个工作示例,您必须考虑每个具有更多字段的构造函数都应该将额外的字段标记为可选。

class LocalError {
  message?: string;
  status?: string;
  details?: Map<string, string>;

  constructor(message: string);
  constructor(message?: string, status?: string);
  constructor(message?: string, status?: string, details?: Map<string, string>) {
    this.message = message;
    this.status = status;
    this.details = details;
  }
}

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

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

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

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