Daktilo Oluşturucu aşırı yük

oy
216

Daktilo kimse yapılan yapıcı aşırı yüklemesini sahiptir. dil şartnamede (v 0.8) sayfa 64 günü, yapıcı aşırı yükleri anlatan ifadeler var ama verilen herhangi bir örnek kod yoktu.

Ben şu an çok temel sınıf beyanı çalışıyorum; o, şöyle

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

açıktır - tsc BoxSample.ts ile bittikçe daha yinelenen bir yapıcı tanımını dışarı atar. Herhangi bir yardım takdir edilmektedir.

Oluştur 03/10/2012 saat 06:48
kaynak kullanıcı
Diğer dillerde...                            


13 cevaplar

oy
190

Typescript Eğer aşırı yükleri ilan etmek ancak yalnızca bir uygulama olabilir ve bu uygulama, tüm aşırı uyumlu bir imza olması gerekir verir. Örnekte, bu kolayca gibi isteğe bağlı bir parametre ile yapılabilir

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

ya da daha genel bir kurucu ile iki aşırı yükler,

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;
    }   
}
Cevap 03/10/2012 saat 07:14
kaynak kullanıcı

oy
63

Ayrıca typescript, mesela varsayılan parametreler aracılığıyla uygulama düzeyinde aşırı eksikliği gidermek unutmayın:

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

Düzenleme: Aralık 5 '16 itibariyle bakınız Benson cevabı daha fazla esneklik sağlayan bir daha ayrıntılı bir çözüm.

Cevap 09/10/2012 saat 07:29
kaynak kullanıcı

oy
48

İlgili yapıcı overloads bir alternatif gibi ek aşırı yükleri uygulamak olacaktır statik fabrika yöntemlerle . Ben onun daha okunabilir ve çağrı argümanları test daha az kafa karıştırıcı olduğunu düşünüyorum. İşte basit bir örnek:

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

Daktilo Yöntem aşırı yükleme gerçek için değil her ne pahasına olursa o kaçınıyorum çok fazla derleyici tarafından oluşturulan kodu ve çekirdek ekibi gerektirecek gibi, diyelim. Şu dile mevcut olması aşırı yöntemi için temel sebebi kendi API sihirli argümanlarla kütüphaneler için bildirimleri yazmak için bir yol sağlamaktır. Eğer farklı iddia setlerini işlemek için başınıza bütün ağır yük kaldırma yapmak gerekir beri aşırı yükleri yerine ayrılmış yöntemler kullanılarak çok avantaj görmüyorum.

Cevap 31/07/2016 saat 21:08
kaynak kullanıcı

oy
38

Not: Bu basitleştirilmiş ve typescript 2.1 yansıtacak şekilde 4/13/2017 güncellendi, typescript 1.8 yanıt için geçmişini görmek.

Eğer nesne parametresi isteğe olmak istiyorum gibi geliyor ve aynı zamanda nesnenin özelliklerin her biri isteğe bağlı olarak. Örnek olarak, belirtildiği gibi, aşırı yük söz dizimi gerekli değildir. Burada bazı yanıtlar bazı kötü uygulamalara işaret etmek istedik. Verilmiş, esasen yazı mümkün olan en küçük ifadesi değil box = { x: 0, y: 87, width: 4, height: 0 }, ama bu anlatıldığı gibi belki sınıftan tercih edebilir tüm Kod ipucu incelikler içerir. Bu örnek, biri kısmı, tümü ile bir işlevi çağırmak için izin verir veya parametrelerin hiçbiri hala varsayılan değerler olsun.

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

Bu tanımlanmış nesnenin tüm özelliklerine sahip olmayabilir parametreler için yazmaya çok güvenli bir yoldur. Artık güvenle Bunlardan herhangi yazabilirsiniz:

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

Derleyen, isteğe bağlı parametreler gerçekten yaygın olarak kullanılan eksikliklerini artık (ama hata eğilimli) ait yedek sözdizimi ondan, isteğe olduğunu görüyoruz var = isOptional || default;karşı denetleyerek void 0için kısaltmadır, undefined:

Derleyen Çıktı

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

Zeyilname: Varsayılan değerleri ayarlanıyor: yanlış yol

||(Ya da) operatör

Tehlikesini düşünün ||diğer bazı cevaplar gösterildiği gibi, varsayılan yedek değerleri belirlerken / veya operatörleri. Bu kod aşağıda varsayılan ayarlamak için yanlış bir şekilde göstermektedir. Karşı değerlendirirken, beklenmeyen sonuçlar elde edebilirsiniz Falsey 0 gibi değerler '', null, tanımsız, yanlış, 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 (bu, obj)

ES6 / typescript Bozunmamış nesneyi kullanarak testlerde, içinde Object.assign daha neredeyse% 90 daha hızlı olabilir . Da tahrip edilen parametreyi kullanmak sadece nesneye atadığınız yöntemleri ve özellikleri sağlar. Örneğin, bu yöntemi göz önünde bulundurun:

class BoxTest {
    public x?: number = 1;

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

Başka bir kullanıcı, ait değildi bir parametre yerleştirmek için typescript kullanarak ve teşebbüs değildi Eğer diyelim ki, onlar koyarak deneyebilirsiniz zözelliği

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')
Cevap 05/12/2016 saat 14:30
kaynak kullanıcı

oy
32

Bu eski bir soru ama 1.4 yeni birlik tipleri olduğunu biliyoruz; (Kurucular dahil) tüm işlev aşırı için bunları kullanabilir. Örnek:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);
Cevap 04/02/2015 saat 18:28
kaynak kullanıcı

oy
20

Güncelleme (2017 8 Haziran): guyarad ve benim cevap için aşağıdaki görüşlerini geçerli puan yapmak snolflake. Ben okuyucular tarafından cevaplara bakmak öneriyoruz Benson , Joe ve snolflake benimkinden daha iyi cevaplar var.

Orijinal Cevap (2014 27 Ocak)

yapıcı aşırı yüklemesini nasıl ulaşılacağını bir başka örneği:

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

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

Cevap 27/01/2014 saat 17:02
kaynak kullanıcı

oy
3

isteğe bağlı, daktilo parametre yeterince iyi olduğu durumda, özellikleri tekrar ya da bir ara tanımlamadan aynı işlevi şu kodu göz önünde bulundurun:

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

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

Bu geçirilen tüm özellikleri atar unutmayın trackonlar üzerinde tanımlı değilseniz, arifesinde Track.

Cevap 06/11/2016 saat 00:22
kaynak kullanıcı

oy
1

Buna göre işleyebilir:

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

Birden kurucular izin Alanlarınızı (x, y, boy, genişlik) isteğe bağlı öğeleri, yapacak Kısmi

örneğin: Yapabileceğiniz new Box({x,y})yükseklik ve genişlik olmadan.

= {}Böyle tanımsız null vb olarak falsy değerini idare edecek ve sonra yapabileceğiniznew Box()

Cevap 11/09/2018 saat 09:36
kaynak kullanıcı

oy
1

varsayılan değerler ve yayılma sözdizimi kullanılarak @ ShinNoNoir koduyla gibi başka bir sürümü:

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;
    }
}
Cevap 30/11/2016 saat 05:11
kaynak kullanıcı

oy
0

Varsayılan / isteğe bağlı params almak ve aşağıdaki alternatif kullanın "tür-of-aşırı" params değişken sayısı ile kurucular:

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

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

Ben hiç güzel kod olmadığını biliyorum, ama bir buna alışır. Arayüz kullanırken mümkün değildir ek Arayüz ihtiyacı ve özel üyelerini tanır.

Cevap 20/09/2019 saat 14:28
kaynak kullanıcı

oy
0

Aslında bu yanıt için çok geç olabilir ama şimdi bunu yapabilirsiniz:

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

böylece yerine statik yöntemlerin yukarıda yapabilirsiniz. Umarım bu sana yardımcı olur!!!

Cevap 26/05/2019 saat 23:31
kaynak kullanıcı

oy
0

Biz kullanarak yapıcı aşırı simüle edebilirsiniz korumaları

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" })
Cevap 27/03/2019 saat 00:18
kaynak kullanıcı

oy
0

Aklında o vardı gerekir ...

contructor ()

Yapıcı (a: bir b: herhangi c: herhangi bir)

Bu aynı olduğunu

(Yeni) ya da yeni ( "a", "b", "c")

Böylece

Yapıcı (a: Herhangi b: Herhangi, C: Herhangi), yukarıdaki ile aynı olduğu ve daha esnektir ...

(Yeni) ya da yeni ( "a") ya da yeni ( "a", "B"), ya da yeni ( "a", "b", "c")

Cevap 02/06/2018 saat 14:15
kaynak kullanıcı

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