टाइपप्रति में निर्माता अधिभार

वोट
216

टाइपप्रति में किसी को भी किया निर्माता से अधिक भार है। भाषा विनिर्देश (V 0.8) के पेज 64 पर, वहाँ निर्माता भार के वर्णन कर बयान कर रहे हैं, लेकिन वहाँ किसी भी नमूने दिए गए कोड नहीं था।

मैं अभी एक वास्तव में बुनियादी वर्ग घोषणा बाहर कोशिश कर रहा हूँ; यह इस तरह दिख रहा है,

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

जो स्पष्ट है - जब tsc BoxSample.ts साथ भाग गया, उसे डुप्लिकेट निर्माता परिभाषा बाहर फेंकता है। किसी भी मदद की सराहना की है।

03/10/2012 को 06:48
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


13 जवाब

वोट
190

टाइपप्रति आप भार के घोषित लेकिन आप केवल एक कार्यान्वयन हो सकता है और है कि कार्यान्वयन एक हस्ताक्षर है कि सभी भार के साथ संगत है होना आवश्यक है करने के लिए अनुमति देता है। अपने उदाहरण में, यह आसानी से के रूप में में एक वैकल्पिक पैरामीटर के साथ किया जा सकता है,

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

या के रूप में में एक अधिक सामान्य निर्माता के साथ दो भार के,

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;
    }   
}
03/10/2012 को 07:14
का स्रोत उपयोगकर्ता

वोट
63

ध्यान दें कि आप भी टाइपप्रति, जैसे में डिफ़ॉल्ट पैरामीटर के माध्यम से कार्यान्वयन के स्तर पर अधिक भार की कमी को हल करने के कर सकते हैं:

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

संपादित करें: दिसंबर 5 '16 के रूप में, देखने के बेन्सन जवाब एक अधिक विस्तृत समाधान है कि और अधिक लचीलापन देता है के लिए।

09/10/2012 को 07:29
का स्रोत उपयोगकर्ता

वोट
48

के बारे में निर्माता overloads एक विकल्प के रूप में अतिरिक्त भार के लागू करने के लिए किया जाएगा स्थिर कारखाने तरीकों । मैं अपने अधिक पठनीय और अपने कॉल तर्क परीक्षण की तुलना में कम भ्रामक लगता है। ये रहा एक सरल उदाहरण:

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

टाइपप्रति में विधि ओवरलोडिंग असली के लिए नहीं है ,, मान लें के रूप में यह है कि से बचने के लिए हर कीमत पर कोशिश बहुत ज्यादा संकलक उत्पन्न कोड और कोर टीम की आवश्यकता होगी। वर्तमान में विधि भाषा पर उपस्थित होने का अधिक भार के लिए मुख्य कारण एक तरह से उनके एपीआई में जादू तर्क के साथ पुस्तकालयों के लिए घोषणाओं लिखने के लिए प्रदान करना है। जब से तुम तर्क के विभिन्न सेट को संभालने के लिए खुद ही सभी भारी उठाने करने की आवश्यकता होगी मैं अलग तरीकों के बजाय भार के का उपयोग कर में कोई खास लाभ नहीं दिख रहा।

31/07/2016 को 21:08
का स्रोत उपयोगकर्ता

वोट
38

नोट: इस सरल और 2017/04/13 अद्यतन टाइपप्रति 2.1 प्रतिबिंबित करने के लिए किया गया था, टाइपप्रति 1.8 जवाब के लिए इतिहास को देखते हैं।

ऐसा लगता है कि आप वस्तु पैरामीटर वैकल्पिक होना चाहता हूँ, और यह भी वस्तु में संपत्तियों में से प्रत्येक वैकल्पिक किया जाना है। उदाहरण में, के रूप में प्रदान की है, अधिभार वाक्य रचना की जरूरत नहीं है। मैं जवाब यहां से कुछ में कुछ बुरी प्रथाएँ करना चाहता था। दी, यह अनिवार्य रूप से लिखने की छोटी संभव अभिव्यक्ति नहीं है box = { x: 0, y: 87, width: 4, height: 0 }, लेकिन यह सब कोड इशारा ब्योरा के रूप में वर्णित आप संभवतः वर्ग से चाहते सकता है प्रदान करता है। यह उदाहरण आपको एक, कुछ, सब, के साथ एक समारोह कॉल करने के लिए अनुमति देता है या कोई भी मानकों के हैं और अभी भी मूलभूत मूल्यों मिलता है।

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

यह एक बहुत ही सुरक्षित तरीका मापदंडों वस्तु परिभाषित के सभी गुण नहीं हो सकता है कि के लिए लिखने के लिए है। अब आप सुरक्षित रूप से इनमें से किसी भी लिख सकते हैं:

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

संकलित, आप देखते हैं कि वैकल्पिक पैरामीटर सही मायने में वैकल्पिक हैं, कि (लेकिन त्रुटियों की संभावना) एक व्यापक रूप से इस्तेमाल के नुकसान से बचा जाता है वापस आने की वाक्य रचना var = isOptional || default;के खिलाफ जाँच करके void 0, जो के लिए आशुलिपि है undefined:

संकलित आउटपुट

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

परिशिष्ट: मूलभूत मूल्यों की स्थापना: गलत तरीके से

||(या) ऑपरेटर

के खतरे पर विचार करें ||जब डिफ़ॉल्ट फ़ॉलबैक मान सेट के रूप में कुछ अन्य उत्तर में दिखाया गया है / या ऑपरेटरों। नीचे इस कोड को डिफ़ॉल्ट सेट करने गलत तरीके से दिखाता है। जब के खिलाफ का मूल्यांकन आप अप्रत्याशित परिणाम प्राप्त कर सकते हैं falsey 0 की तरह मान, ', अशक्त, अपरिभाषित, झूठे, 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 (यह, obj)

मेरी परीक्षण, ES6 / टाइपप्रति destructured वस्तु का उपयोग करने में लगभग 90% Object.assign तुलना में तेजी से हो सकता है । एक destructured पैरामीटर का उपयोग केवल अनुमति देता है तरीकों और गुण आप वस्तु को निर्दिष्ट किए गए। उदाहरण के लिए, इस विधि पर विचार करें:

class BoxTest {
    public x?: number = 1;

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

किसी अन्य उपयोगकर्ता टाइपप्रति का उपयोग नहीं किया गया था और कोशिश की एक पैरामीटर है कि संबंधित नहीं थे, जगह कहते हैं, वे एक डाल की कोशिश कर सकते zसंपत्ति

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')
05/12/2016 को 14:30
का स्रोत उपयोगकर्ता

वोट
32

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन 1.4 में नया संघ प्रकार है; सभी कार्य भार के (निर्माताओं सहित) के लिए इन का उपयोग करें। उदाहरण:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);
04/02/2015 को 18:28
का स्रोत उपयोगकर्ता

वोट
20

अद्यतन (8 जून 2017): guyarad और मेरे जवाब देने के लिए नीचे अपनी टिप्पणी में मान्य अंक बनाने snolflake। मैं सिफारिश करेंगे पाठकों द्वारा जवाब को देखो बेन्सन , जो और snolflake जो मेरा की तुलना में बेहतर जवाब।

मूल उत्तर (27 जनवरी 2014)

कैसे निर्माता से अधिक भार प्राप्त करने के लिए का एक और उदाहरण:

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

स्रोत: http://mimosite.com/blog/post/2013/04/08/Overloading-in-TypeScript

27/01/2014 को 17:02
का स्रोत उपयोगकर्ता

वोट
3

इस मामले में जहां एक वैकल्पिक, आपके द्वारा लिखा गया पैरामीटर काफी अच्छा है, निम्नलिखित कोड जो गुण दोहरा या एक इंटरफेस को परिभाषित करने के बिना एक ही सिद्ध पर विचार करें:

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

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

ध्यान रखें कि यह सभी गुण में पारित आवंटित करेगा trackअगर वे पर परिभाषित नहीं कर रहे हैं, पूर्व संध्या Track

06/11/2016 को 00:22
का स्रोत उपयोगकर्ता

वोट
1

आपके द्वारा इस संभाल कर सकते हैं:

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

आंशिक कई निर्माताओं के लिए अनुमति देता है अपने क्षेत्र (एक्स, वाई, ऊंचाई, चौड़ाई) optionals, कर देगा

उदाहरण के लिए: आप कर सकते हैं new Box({x,y})ऊंचाई, चौड़ाई और बिना।

= {}ऐसे अपरिभाषित, अशक्त आदि के रूप में falsy मूल्य संभाल लेंगे, और फिर आप क्या कर सकते हैंnew Box()

11/09/2018 को 09:36
का स्रोत उपयोगकर्ता

वोट
1

@ ShinNoNoir के कोड में की तरह एक और संस्करण, मूलभूत मूल्यों और प्रसार सिंटैक्स का उपयोग:

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;
    }
}
30/11/2016 को 05:11
का स्रोत उपयोगकर्ता

वोट
0

मैं निम्नलिखित विकल्प का उपयोग डिफ़ॉल्ट / वैकल्पिक पैरामीटर प्राप्त करने के लिए और "प्रकार के- अतिभारित" पैरामीटर की चर संख्या के साथ कंस्ट्रक्टर:

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

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

मैं जानता हूँ कि यह सबसे सुंदर कोड कभी नहीं है, लेकिन एक यह करने के लिए इस्तेमाल किया जाता है। अतिरिक्त इंटरफ़ेस के लिए कोई ज़रूरत नहीं है और यह निजी सदस्यों की अनुमति देता है, जो संभव नहीं है जब इंटरफ़ेस का उपयोग कर।

20/09/2019 को 14:28
का स्रोत उपयोगकर्ता

वोट
0

वास्तव में यह इस उत्तर के लिए बहुत देर हो चुकी हो सकता है, लेकिन आप अब ऐसा कर सकते हैं:

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

तो बजाय स्थिर तरीकों में से आप ऊपर कर सकते हैं। मुझे आशा है कि यह आपकी मदद करेगा!!!

26/05/2019 को 23:31
का स्रोत उपयोगकर्ता

वोट
0

हम का उपयोग कर निर्माता अधिभार अनुकरण कर सकते हैं गार्ड

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" })
27/03/2019 को 00:18
का स्रोत उपयोगकर्ता

वोट
0

आप ध्यान रखें कि में था चाहिए ...

contructor ()

निर्माता (एक: किसी भी, ख: किसी भी, सी: किसी भी)

यह का एक ही है

नई () या नए ( "एक", "ख", "ग")

इस प्रकार

निर्माता (एक: किसी भी, ख: किसी भी, सी: किसी भी) के ऊपर ही है और अधिक लचीला है ...

नई () या नए ( "एक") या नए ( "एक", "ख") या नए ( "एक", "ख", "ग")

02/06/2018 को 14:15
का स्रोत उपयोगकर्ता

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