Constructor overbelasting schrijfmachine

stemmen
216

Heeft iemand gedaan constructeur overbelasting met de schrijfmachine. Op bladzijde 64 van de taalspecificatie (v 0.8), zijn vermeld die constructor overbelasting, maar er was geen voorbeeld gegeven code.

Ik probeer een erg basic klasse verklaring op dit moment; het ziet er zo uit,

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

Toen liep met TSC BoxSample.ts, gooit uit een duplicaat bouwer definitie - en dat is duidelijk. Alle hulp wordt gewaardeerd.

De vraag is gesteld op 03/10/2012 om 06:48
bron van user
In andere talen...                            


13 antwoorden

stemmen
190

Typescript stelt u in staat om overbelasting te verklaren, maar je kunt slechts één uitvoering en dat de uitvoering moet een handtekening die compatibel is met alle overbelasting is hebben. In uw voorbeeld, kan dit gemakkelijk worden gedaan met een optionele parameter als 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;
    }   
}

of twee overbelasting met een meer algemene aannemer als 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;
    }   
}
antwoordde op 03/10/2012 om 07:14
bron van user

stemmen
63

Merk op dat u ook kunt werken rond het ontbreken van overbelasting bij de uitvoering niveau door middel van standaard parameters in typoscript, bijvoorbeeld:

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: Met ingang van 5 december '16, zie antwoord Benson's voor een meer uitgebreide oplossing die meer flexibiliteit mogelijk maakt.

antwoordde op 09/10/2012 om 07:29
bron van user

stemmen
48

Met betrekking tot constructeur overbelasting een alternatief zou zijn om de extra overbelasting te voeren zoals statische fabriek methoden . Ik denk dat het beter leesbaar en minder verwarrend dan het testen van uw oproep argumenten. Hier is een eenvoudig voorbeeld:

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'
})

Methode overbelasting schrijfmachine is niet voor echt , laten we zeggen, omdat het te veel-compiler gegenereerde code en het kernteam zou moeten proberen te voorkomen dat ten koste van alles. Momenteel is de belangrijkste reden voor de methode overbelasting aanwezig zijn op de taal te zijn is het een manier om declaraties voor bibliotheken met magische argumenten in hun API te schrijven bieden. Omdat je nodig hebt om al het zware werk doen door uzelf op verschillende reeksen argumenten hanteren Ik heb niet veel voordeel zien in het gebruik van overbelasting in plaats van gescheiden methoden.

antwoordde op 31/07/2016 om 21:08
bron van user

stemmen
38

Let op: deze werd vereenvoudigd en gemoderniseerd 2017/04/13 om typoscript 2.1 weer te geven, zie de geschiedenis voor Typescript 1,8 antwoord.

Het klinkt als u wilt dat de parameter object optioneel zijn, en ook elk van de woningen in het object optioneel zijn. In het voorbeeld, zoals voorzien, overbelasting syntax is niet noodzakelijk. Ik wilde wijzen op een aantal slechte praktijken in het deel van de antwoorden. Toegegeven, het is niet de kleinst mogelijke uitdrukking van wezen schrijven box = { x: 0, y: 87, width: 4, height: 0 }, maar dit biedt alle codehints finesses u eventueel wilt uit de klasse zoals beschreven. In dit voorbeeld kunt u een functie aan te roepen met één enkele, alle, of geen van de parameters en nog steeds standaardwaarden.

 /** @class */
 class Box {
     public x?: number;
     public y?: number;
     public height?: number;
     public width?: number;     

     // The class can work double-duty as the interface here since they are identical
     // Alternately, reference your own interface, e.g.:  `...BoxI = {} as BoxI` 
     constructor(obj: Box = {} as Box) {

         // Define the properties of the incoming `obj` object here. 
         // Setting a default value with the `= 0` syntax is optional for each parameter
         let {
             x = 0,
             y = 0,
             height = 0,
             width = 0
         } = obj;

         /** Use jsdoc comments here for inline ide auto-documentation */
         this.x = x;
         this.y = y;
         this.height = height;
         this.width = width;
     }
 }

Dit is een zeer veilige manier om te schrijven voor parameters die niet alle eigenschappen van het object bepaald kan hebben. U kunt nu veilig schrijven een van deze:

const box1 = new Box();
const box2 = new Box({});
const box3 = new Box({x:0});
const box4 = new Box({x:0, height:10});
const box5 = new Box({x:0, y:87,width:4,height:0});

 // Correctly reports error in TypeScript, and in js, box6.z is undefined
const box6 = new Box({z:0});  

Samengesteld, zie je dat de optionele parameters werkelijk zijn optioneel, dat de valkuilen van een veelgebruikt vermijdt (maar foutgevoelige) fallback syntaxis van var = isOptional || default;door te controleren tegen void 0, dat is een afkorting voor undefined:

De gecompileerde Output

var Box = (function () {
    function Box(obj) {
        if (obj === void 0) { obj = {}; }
        var _a = obj.x, 
        x = _a === void 0 ? 1 : _a,
        _b = obj.y,
        y = _b === void 0 ? 1 : _b,
        _c = obj.height,
        height = _c === void 0 ? 1 : _c,
        _d = obj.width,
        width = _d === void 0 ? 1 : _d;
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
    }
    return Box;
}());

Addendum: Instelling standaardwaarden: de verkeerde manier

De ||(OR)

Denk aan het gevaar van ||/ of operators bij het instellen van standaard fallback waarden zoals in sommige andere antwoorden. Onder deze code illustreert de verkeerde manier om de standaardinstellingen in te stellen. U kunt onverwachte resultaten krijgen bij het evalueren tegen falsey waarden als 0, '', null, undefined, vals, NaN:

var myDesiredValue = 0;
var result = myDesiredValue || 2;

// This test will correctly report a problem with this setup.
console.assert(myDesiredValue === result && result === 0, 'Result should equal myDesiredValue. ' + myDesiredValue + ' does not equal ' + result);

Object.assign (deze, obj)

In mijn tests, met behulp van ES6 / typoscript gedestructureerd object kan bijna 90% sneller dan Object.assign zijn . Met behulp van een gedestructureerd parameter kan alleen methoden en eigenschappen die u aan het object hebt toegewezen. Denk bijvoorbeeld aan deze methode:

class BoxTest {
    public x?: number = 1;

    constructor(obj: BoxTest = {} as BoxTest) {
        Object.assign(this, obj);
    }
}

Als een andere gebruiker niet werd gebruikt Typescript en geprobeerd om een parameter die niet behoren, plaatsen we zeggen, zouden ze proberen zetten een zwoning

var box = new BoxTest({x: 0, y: 87, width: 4, height: 0, z: 7});

// This test will correctly report an error with this setup. `z` was defined even though `z` is not an allowed property of obj.
console.assert(typeof box.z === 'undefined')
antwoordde op 05/12/2016 om 14:30
bron van user

stemmen
32

Ik weet dat dit een oude vraag, maar nieuw in 1.4 is types unie; gebruik maken van deze voor alle functie-overbelasting (inclusief constructeurs). Voorbeeld:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);
antwoordde op 04/02/2015 om 18:28
bron van user

stemmen
20

Update (8 juni 2017): guyarad en snolflake maken geldig punten in hun opmerkingen hieronder om mijn antwoord. Ik zou aanraden lezers kijken naar de antwoorden van Benson , Joe en snolflake die betere antwoorden dan de mijne.

Original Antwoord (27 januari 2014)

Een ander voorbeeld van hoe bouwer overbelasting te bereiken:

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

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

antwoordde op 27/01/2014 om 17:02
bron van user

stemmen
3

In het geval waarin een optionele parameter getypte goed genoeg, de volgende code die hetzelfde bewerkstelligt zonder herhaling van de eigenschappen of het definiëren van een interface:

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

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

Houd in gedachten dat dit zal alle eigenschappen doorgegeven in toewijzen track, vooravond als ze niet gedefinieerd op Track.

antwoordde op 06/11/2016 om 00:22
bron van user

stemmen
1

U kunt dit aan door:

import { assign } from 'lodash'; // if you don't have lodash use Object.assign
class Box {
    x: number;
    y: number;
    height: number;
    width: number;
    constructor(obj: Partial<Box> = {}) {    
         assign(this, obj);
    }
}

Gedeeltelijke uw akkers (x, y, hoogte, breedte) optionals, waardoor meerdere constructeurs maken

bijvoorbeeld: je kunt doen new Box({x,y})zonder in hoogte en breedte.

Het = {}zal falsy waarde behandelen zoals ongedefinieerd, null etc, en dan kun je doennew Box()

antwoordde op 11/09/2018 om 09:36
bron van user

stemmen
1

Een andere versie, zoals naar @ ShinNoNoir's code, met behulp van standaardwaarden en de verspreiding syntax:

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

    constructor({x, y, height, width}: IBox = { x: 0, y: 0, height: 0, width: 0 }) {
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
    }
}
antwoordde op 30/11/2016 om 05:11
bron van user

stemmen
0

Ik gebruik de volgende alternatief voor de standaard / optionele params te krijgen en "-kind-of overbelast" constructeurs met een variabel aantal params:

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

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

Ik weet dat het niet de mooiste code ooit, maar het went het. Geen behoefte aan de extra interface en het staat particuliere leden, wat niet mogelijk is bij gebruik van de interface.

antwoordde op 20/09/2019 om 14:28
bron van user

stemmen
0

Eigenlijk is het misschien te laat voor dit antwoord, maar u kunt dit nu doen:

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

Dus in plaats van statische methoden kunt u het bovenstaande te doen. Ik hoop dat het zal u helpen !!!

antwoordde op 26/05/2019 om 23:31
bron van user

stemmen
0

We kunnen constructor overload simuleren met behulp van guards

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" })
antwoordde op 27/03/2019 om 00:18
bron van user

stemmen
0

Je moet in gedachten had dat ...

contructor ()

constructor (a: elk, b: elk, c: eventueel)

Het is hetzelfde van

nieuwe () of nieuwe ( "a", "b", "c")

Dus

constructor (a: elk, b: elk, c: alle) hetzelfde hierboven en flexibeler ...

nieuwe () of nieuwe ( "a") of nieuwe ( "a", "b") of nieuwe ( "a", "b", "c")

antwoordde op 02/06/2018 om 14:15
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more