TypeScript中的构造方法重载

本文翻译自:Constructor overload in TypeScript

Has anybody done constructor overloading in TypeScript. 是否有人在TypeScript中完成了构造函数重载。 On page 64 of the language specification (v 0.8), there are statements describing constructor overloads, but there wasn't any sample code given. 在语言规范(v 0.8)的第64页上,有描述构造函数重载的语句,但是没有给出任何示例代码。

I'm trying out a really basic class declaration right now; 我现在正在尝试一个非常基本的类声明; it looks like this, 看起来像这样

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;
    }
}

When ran with tsc BoxSample.ts, it throws out a duplicate constructor definition -- which is obvious. 当与tsc BoxSample.ts一起运行时,它将抛出重复的构造函数定义-这是显而易见的。 Any help is appreciated. 任何帮助表示赞赏。


#1楼

参考:https://stackoom.com/question/rIVo/TypeScript中的构造方法重载


#2楼

TypeScript allows you to declare overloads but you can only have one implementation and that implementation must have a signature that is compatible with all overloads. TypeScript允许您声明重载,但只能有一个实现,并且该实现必须具有与所有重载兼容的签名。 In your example, this can easily be done with an optional parameter as in, 在您的示例中,可以使用可选参数轻松完成此操作,如下所示:

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 && obj.x || 0
        this.y = obj && obj.y || 0
        this.height = obj && obj.height || 0
        this.width = obj && obj.width || 0;
    }   
}

or two overloads with a more general constructor as in, 或两个更普通的构造函数的重载,

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?: any) {    
        this.x = obj && obj.x || 0
        this.y = obj && obj.y || 0
        this.height = obj && obj.height || 0
        this.width = obj && obj.width || 0;
    }   
}

#3楼

Note that you can also work around the lack of overloading at the implementation level through default parameters in TypeScript, eg: 请注意,您还可以通过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;
    }   
}

Edit: As of Dec 5 '16, see Benson's answer for a more elaborate solution that allows more flexibility. 编辑:从16年5月5日开始,请参阅Benson的答案以获取更精致的解决方案,该解决方案可以提供更大的灵活性。


#4楼

Update (8 June 2017): guyarad and snolflake make valid points in their comments below to my answer. 更新(2017年6月8日): Guyarad和Snolflake在下面对我的回答的评论中指出了有效的观点。 I would recommend readers look at the answers by Benson , Joe and snolflake who have better answers than mine. 我建议读者阅读本森snolflake的答案,这些答案比我的答案要好。

Original Answer (27 January 2014) 原始答案(2014年1月27日)

Another example of how to achieve constructor overloading: 如何实现构造函数重载的另一个示例:

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;
    }
  }
}

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


#5楼

I know this is an old question, but new in 1.4 is union types; 我知道这是一个老问题,但是1.4中的新问题是联合类型。 use these for all function overloads (including constructors). 将它们用于所有函数重载(包括构造函数)。 Example: 例:

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

#6楼

Regarding constructor overloads one good alternative would be to implement the additional overloads as static factory methods . 关于构造函数重载,一个好的替代方法是将额外的重载实现为静态工厂方法 I think its more readable and simple than checking for all possible argument combinations at the constructor. 我认为它比在构造函数中检查所有可能的参数组合更具可读性和简单性。 Here is a simple example: 这是一个简单的示例:

class Person {
    static fromData(data: PersonData) {
        let { first, last, birthday, gender = 'M' } = data 
        return new this(
            `${last}, ${first}`,
            calculateAge(birthday),
            gender
        )
    }

    constructor(
        public fullName: string,
        public age: number,
        public gender: 'M' | 'F'
    ) {}
}

interface PersonData {
    first: string
    last: string
    birthday: string
    gender?: 'M' | 'F'
}


let personA = new Person('Doe, John', 31, 'M')
let personB = Person.fromData({
    first: 'John',
    last: 'Doe',
    birthday: '10-09-1986'
})

Method overloading in TypeScript isn't for real , let's say, as it would require too much compiler-generated code and the core team try to avoid that at all costs. 可以说,TypeScript中的方法重载并不是真正的,因为这将需要过多的编译器生成的代码,并且核心团队会不惜一切代价避免这种情况。 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. 当前,在语言上出现方法重载的主要原因是提供一种为API中带有魔术参数的库编写声明的方法。 Since you'll need to do all the heavy-lifting by yourself to handle different sets of arguments I don't see much advantage in using overloads instead of separated methods. 因为您需要自己做所有繁重的工作来处理不同的参数集,所以在使用重载而不是单独的方法方面没有多大优势。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值