Konstruktér přetížení na psacím stroji

hlasů
216

Má někdo udělal konstruktoru přetížení na psacím stroji. Na straně 64 specifikaci jazyka (v 0,8), jsou příkazy popisující konstruktoru přetížení, ale nebyl jakýkoliv vzorek kód přiřazený.

Snažím se opravdu základní deklaraci třídy hned; vypadá to, že to,

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

Když běžel s TSC BoxSample.ts, že vyhodí duplicitní definice konstruktoru - což je zřejmý. Každá pomoc je oceňována.

Položena 03/10/2012 v 06:48
zdroj uživatelem
V jiných jazycích...                            


13 odpovědí

hlasů
190

Strojopisem vám umožňuje deklarovat přetížení, ale můžete mít pouze jedno provedení, a že provádění musí mít podpis, který je kompatibilní se všemi přetížení. Ve Vašem příkladu, to může snadno provést pomocí volitelný parametr jako v,

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

nebo dvě přetížení s obecnější konstruktoru jako v,

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;
    }   
}
Odpovězeno 03/10/2012 v 07:14
zdroj uživatelem

hlasů
63

Všimněte si, že můžete také vyřešit nedostatek přetížení na úrovni implementace prostřednictvím výchozích parametrů na stroji, např:

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: Jak XII 5 '16, viz Bensona odpověď pro podrobnější řešení, které umožňuje větší flexibilitu.

Odpovězeno 09/10/2012 v 07:29
zdroj uživatelem

hlasů
48

Co se týče konstruktor přetěžuje jednu Alternativou by bylo zavést dodatečná přetížení jako statické tovární metody . Myslím, že je čitelnější a méně matoucí než otestovat své argumenty volání. Zde je jednoduchý příklad:

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

Metoda přetížení na stroji není pro skutečné , řekněme, protože by to vyžadovalo příliš mnoho kódu kompilátor generované a základní tým se snaží zabránit tomu, aby za každou cenu. V současné době je hlavním důvodem pro metodu přetížení, aby byl přítomen na jazyku je poskytnout způsob, jak psát prohlášení pro knihovny s kouzelnými argumenty v jejich API. Vzhledem k tomu, budete muset udělat všechnu těžkou zvedání sami zvládnout různé sady argumentů Nevidím mnoho výhod při používání přetížení namísto oddělené metody.

Odpovězeno 31/07/2016 v 21:08
zdroj uživatelem

hlasů
38

Poznámka: toto bylo zjednodušeno a aktualizováno 4/13/2017, aby odrážela strojopisu 2.1, viz historii strojopisem 1,8 odpověď.

Vypadá to, že chcete, aby se parametr objekt být nepovinný, a také každý z vlastností v objektu, který má být nepovinný. V tomto příkladu, jak je uvedeno, není potřeba syntax přetížení. Chtěl bych poukázat na některé špatné praktiky se v některé z odpovědí zde. Je pravda, že to není nejmenší výrazem v podstatě psát box = { x: 0, y: 87, width: 4, height: 0 }, ale poskytuje všechny psaní kódu jemnosti byste mohli chtít od třídy, jak je popsáno. Tento příklad umožňuje volání funkce s jedním, některými, všemi, nebo žádný z parametrů a ještě získat výchozí hodnoty.

 /** @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;
     }
 }

Jedná se o velmi bezpečný způsob, jak psát pro parametry, které nemusí mít všechny vlastnosti objektu definován. Nyní můžete bezpečně napsat některý z nich:

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

Sestaven, vidíte, že volitelné parametry skutečně jsou volitelné, který se vyhýbá nástrahám široce používaný (ale náchylné k chybám) nouzový syntaxe var = isOptional || default;kontrolou proti void 0, což je zkratka pro undefined:

Sestavený výstup

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

Dodatek: Nastavení výchozích hodnot: špatně

||(Nebo) provozovatel

Zvážit nebezpečí ||/ nebo operátory při nastavování výchozích hodnot záložní, jak je uvedeno v některých jiných odpovědí. Tento kód níže ukazuje špatně nastavit výchozí hodnoty. Se můžete dostat k neočekávaným výsledkům při vyhodnocování proti Falsey hodnotami, jako je 0, ‚‘, null, nedefinované, falešný 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 (to, obj)

V mých testů, využívajících es6 / strojopisem odbourání objekt může být téměř 90% rychleji než Object.assign . Použití destrukturalizovaného parametr umožňuje pouze metody a vlastnosti, které jste přiřazen k objektu. Vezměme si například tuto metodu:

class BoxTest {
    public x?: number = 1;

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

Pokud jiný uživatel nebyl použití strojopisu a pokoušel se umístit parametr, který nepatří, dejme tomu, že by se mohli pokusit uvedení znemovitosti

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')
Odpovězeno 05/12/2016 v 14:30
zdroj uživatelem

hlasů
32

Vím, že to je stará otázka, ale nové v 1.4 je typy svazů; Pomocí těchto všech funkcí přetížení (včetně konstruktérů). Příklad:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);
Odpovězeno 04/02/2015 v 18:28
zdroj uživatelem

hlasů
20

Update (08.6.2017): guyarad a snolflake aby platné body ve svých připomínkách dále na mou odpověď. Doporučil bych čtenáři se podívat na odpovědi od Benson , Joe a snolflake , kteří mají lepší odpovědi než moje.

Původní odpověď (27 leden 2014)

Dalším příkladem toho, jak dosáhnout konstruktoru přetížení:

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

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

Odpovězeno 27/01/2014 v 17:02
zdroj uživatelem

hlasů
3

V případě, že volitelný, zadali parametr je dost dobrý, zvažte následující kód, který naplňuje stejná bez opakování vlastnosti nebo definování rozhraní:

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

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

Mějte na paměti, to přiřadí všechny vlastnosti předané do track, předvečer když nejsou definovány na Track.

Odpovězeno 06/11/2016 v 00:22
zdroj uživatelem

hlasů
1

Můžete zvládnout tím, že:

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

Částečné bude vaše pole (x, y, výška, šířka) Volitelně, umožňující více konstruktérů

např můžete udělat new Box({x,y})bez výšky a šířky.

= {}Bude zpracovávat falsy hodnotu, jako nedefinované, null ETC, a pak si můžete udělatnew Box()

Odpovězeno 11/09/2018 v 09:36
zdroj uživatelem

hlasů
1

Další verze jako na @ ShinNoNoir je kód, s použitím standardních hodnot a syntaxe spread:

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;
    }
}
Odpovězeno 30/11/2016 v 05:11
zdroj uživatelem

hlasů
0

I použít následující alternativu k získání standardní / volitelná params a „druh-of-přetížené“ konstruktéři s proměnlivým počtem params:

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

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

Vím, že to není nejhezčí kód vůbec, ale zvykne. Není třeba pro další rozhraní a umožňuje soukromých členů, což není možné při použití rozhraní.

Odpovězeno 20/09/2019 v 14:28
zdroj uživatelem

hlasů
0

Ve skutečnosti to může být příliš pozdě na tuto odpověď, ale nyní můžete udělat toto:

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

takže místo statických metod můžete udělat výše. Doufám, že vám pomůže !!!

Odpovězeno 26/05/2019 v 23:31
zdroj uživatelem

hlasů
0

Můžeme simulovat konstruktoru přetížení pomocí stráže

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" })
Odpovězeno 27/03/2019 v 00:18
zdroj uživatelem

hlasů
0

Měli byste měli na paměti, že ...

konstruktor ()

konstruktor (a: všechna, b: všechna, c: všechna)

Je to stejné jako v

nový () nebo nový ( "a", "b", "c")

Tím pádem

konstruktér (a? jakýkoliv, b? jakýkoliv, c: existuje) je stejná výše a je pružnější ...

nový () nebo nový ( "a"), nebo nové ( "a", "b"), nebo nové ( "a", "b", "c")

Odpovězeno 02/06/2018 v 14:15
zdroj uživatelem

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