Constructor overload in TypeScript

前端 未结 16 1988
滥情空心
滥情空心 2020-11-28 00:42

Has anybody done constructor overloading in TypeScript. On page 64 of the language specification (v 0.8), there are statements describing constructor overloads, but there wa

相关标签:
16条回答
  • 2020-11-28 01:38

    Your Box class is attempting to define multiple constructor implementations.

    Only the last constructor overload signature is used as the class constructor implementation.

    In the below example, note the constructor implementation is defined such that it does not contradict either of the preceding overload signatures.

    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 { ... }
    }
    
    0 讨论(0)
  • 2020-11-28 01:40
    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) {
            const { x, y, height, width } = { x: 0, y: 0, height: 0, width: 0, ...obj }
            this.x = x;
            this.y = y;
            this.height = height;
            this.width = width;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 01:41

    You can handle this by :

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

    Partial will make your fields (x,y, height, width) optionals, allowing multiple constructors

    eg: you can do new Box({x,y}) without height, and width.

    0 讨论(0)
  • 2020-11-28 01:44

    In the case where an optional, typed parameter is good enough, consider the following code which accomplishes the same without repeating the properties or defining an interface:

    export class Track {
       public title: string;
       public artist: string;
       public lyrics: string;
    
       constructor(track?: Track) {
         Object.assign(this, track);
       }
    }
    

    Keep in mind this will assign all properties passed in track, eve if they're not defined on Track.

    0 讨论(0)
提交回复
热议问题