टाइपस्क्रिप्ट में मेथड ओवरलोडिंग करने का कोई तरीका है?


109

क्या टाइपस्क्रिप्ट भाषा में विधि ओवरलोडिंग करने का एक तरीका है?

मैं कुछ इस तरह से हासिल करना चाहता हूं:

class TestClass {
    someMethod(stringParameter: string): void {
        alert("Variant #1: stringParameter = " + stringParameter);
    }

    someMethod(numberParameter: number, stringParameter: string): void {
        alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
    }
}

var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");

यहाँ एक उदाहरण है कि मैं क्या नहीं करना चाहता (मुझे वास्तव में जेएस में हैकिंग के उस हिस्से से नफरत है):

class TestClass {
    private someMethod_Overload_string(stringParameter: string): void {
        // A lot of code could be here... I don't want to mix it with switch or if statement in general function
        alert("Variant #1: stringParameter = " + stringParameter);
    }

    private someMethod_Overload_number_string(numberParameter: number, stringParameter: string): void {
        alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
    }

    private someMethod_Overload_string_number(stringParameter: string, numberParameter: number): void {
        alert("Variant #3: stringParameter = " + stringParameter + ", numberParameter = " + numberParameter);
    }

    public someMethod(stringParameter: string): void;
    public someMethod(numberParameter: number, stringParameter: string): void;
    public someMethod(stringParameter: string, numberParameter: number): void;

    public someMethod(): void {
        switch (arguments.length) {
        case 1:
            if(typeof arguments[0] == "string") {
                this.someMethod_Overload_string(arguments[0]);
                return;
            }
            return; // Unreachable area for this case, unnecessary return statement
        case 2:
            if ((typeof arguments[0] == "number") &&
                (typeof arguments[1] == "string")) {
                this.someMethod_Overload_number_string(arguments[0], arguments[1]);
            }
            else if ((typeof arguments[0] == "string") &&
                     (typeof arguments[1] == "number")) {
                this.someMethod_Overload_string_number(arguments[0], arguments[1]);
            }
            return; // Unreachable area for this case, unnecessary return statement
        }
    }
}


var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
testClass.someMethod("string for v#3", 54321);

1
हां, एक मौका है, भाषा अभी मरा नहीं है। कोई और प्रश्न?
हकरे

6
@hakre यह कहने के लिए एक अजीब बात है, टाइपस्क्रिप्ट पर विचार पहले से ही समर्थन विधि को ओवरलोडिंग करता है।
svick

@ svick: ठीक है, क्या आप उस विधि को ओवरलोडिंग कहते हैं? आपके उत्तर में विधि स्वयं अधिभारित नहीं है, एक शरीर अगर इर्द-गिर्द।
हकर्रे

2
@hakre विनिर्देशन इसे ओवरलोडिंग का तरीका कहता है। आप निश्चित रूप से तर्क दे सकते हैं कि यह इसका विशेष रूप से अच्छा संस्करण नहीं है, लेकिन मुझे लगता है कि आप यह नहीं कह सकते कि यह बिल्कुल भी मौजूद नहीं है।
svick

@ शविक: मैंने या तो नहीं कहा। लेकिन यह मुझे दिखता है कि ओपी के बारे में पूछे जाने वाले मौके मानसिक रूप से ओवरलोडिंग की विधि के बारे में विशिष्ट हैं। बाल-विभाजन के लिए हम कह सकते हैं कि यह विधि हस्ताक्षर अतिभार है;)
hakre

जवाबों:


165

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

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

class TestClass {
    someMethod(stringParameter: string): void;
    someMethod(numberParameter: number, stringParameter: string): void;

    someMethod(stringOrNumberParameter: any, stringParameter?: string): void {
        if (stringOrNumberParameter && typeof stringOrNumberParameter == "number")
            alert("Variant #2: numberParameter = " + stringOrNumberParameter + ", stringParameter = " + stringParameter);
        else
            alert("Variant #1: stringParameter = " + stringOrNumberParameter);
    }
}

3
@NicoVanBelle जावास्क्रिप्ट बिल्कुल, ओवरलोडिंग की विधि का समर्थन नहीं करता है, है ना? तो जेएस कैसे मदद करने जा रहा है?
svick

इंटरफेस की जाँच के बारे में क्या? क्या आपके पास इससे बेहतर समाधान है: stackoverflow.com/questions/14425568/… ?
दीपिक्स

हम्म .. मैं वास्तव में इस तरह नहीं है, सिर्फ एक वैकल्पिक पैरामीटर होने के बजाय पढ़ने के लिए बेहतर है।
LuckyLikey

3
मुझे लगता है कि यहां जो महत्वपूर्ण है, वह यह है कि अगर कोई बयान टाइप किए बिना एक दिन में आपके कोड को बिना पढ़े रखा जा सके। कौन परवाह करता है कि यह किस में परिवर्तित होता है।
ब्रेन २००

34

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

अपना कोड लिखते समय, हालांकि, आप वैकल्पिक या डिफ़ॉल्ट मापदंडों का उपयोग करके ओवरलोड के संज्ञानात्मक ओवरहेड से बचने में सक्षम हो सकते हैं। यह विधि अधिभार के लिए अधिक पठनीय विकल्प है और आपके एपीआई को भी ईमानदार रखता है क्योंकि आप अनजाने क्रम से ओवरलोड बनाने से बचेंगे।

टाइपस्क्रिप्ट ओवरलोड का सामान्य नियम है:

यदि आप ओवरलोड हस्ताक्षर और आपके सभी परीक्षण पास कर सकते हैं, तो आपको टाइपस्क्रिप्ट ओवरलोड की आवश्यकता नहीं है

आप आमतौर पर वैकल्पिक, या डिफ़ॉल्ट मापदंडों - या संघ प्रकारों के साथ, या ऑब्जेक्ट-ओरिएंटेशन के साथ एक ही चीज़ प्राप्त कर सकते हैं।

वास्तविक प्रश्न

वास्तविक सवाल एक अधिभार के लिए पूछता है:

someMethod(stringParameter: string): void {

someMethod(numberParameter: number, stringParameter: string): void {

अब उन भाषाओं में भी जो अलग-अलग कार्यान्वयन के साथ ओवरलोड का समर्थन करते हैं (नोट: टाइपस्क्रिप्ट ओवरलोड एक एकल कार्यान्वयन साझा करते हैं) - प्रोग्रामर आदेश देने में स्थिरता प्रदान करने के लिए सलाह देते हैं। इससे हस्ताक्षर बनेंगे:

someMethod(stringParameter: string): void {

someMethod(stringParameter: string, numberParameter: number): void {

stringParameterहमेशा की तरह, आवश्यक तो यह पहले से चला जाता है है। आप इसे वर्क टाइप ओवरलोड के रूप में लिख सकते हैं:

someMethod(stringParameter: string): void;
someMethod(stringParameter: string, numberParameter: number): void;
someMethod(stringParameter: string, numberParameter?: number): void {
    if (numberParameter != null) {
        // The number parameter is present...
    }
}

लेकिन टाइपस्क्रिप्ट ओवरलोड के कानून के बाद, हम ओवरलोड हस्ताक्षर हटा सकते हैं और हमारे सभी परीक्षण अभी भी पास होंगे।

someMethod(stringParameter: string, numberParameter?: number): void {
    if (numberParameter != null) {
        // The number parameter is present...
    }
}

वास्तविक प्रश्न, वास्तविक क्रम में

यदि आप मूल आदेश के साथ बने रहने के लिए दृढ़ थे, तो ओवरलोड होंगे:

someMethod(stringParameter: string): void;
someMethod(numberParameter: number, stringParameter: string): void;
someMethod(a: string | number, b?: string | number): void {
  let stringParameter: string;
  let numberParameter: number;

  if (typeof a === 'string') {
    stringParameter = a;
  } else {
    numberParameter = a;

    if (typeof b === 'string') {
      stringParameter = b;
    }
  }
}

अब यह है कि मापदंडों को रखने के लिए बहुत सारे ब्रांचिंग किए गए हैं, लेकिन आप वास्तव में इस आदेश को संरक्षित करना चाहते हैं यदि आप इसे दूर पढ़ रहे हैं ... लेकिन रुको, अगर हम टाइपस्क्रिप्ट ओवरलोड के कानून को लागू करते हैं तो क्या होता है?

someMethod(a: string | number, b?: string | number): void {
  let stringParameter: string;
  let numberParameter: number;

  if (typeof a === 'string') {
    stringParameter = a;
  } else {
    numberParameter = a;

    if (typeof b === 'string') {
      stringParameter = b;
    }
  }
}

पहले से ही पर्याप्त

बेशक, हमें जिस प्रकार की जाँच करने की आवश्यकता है, उसे देखते हुए ... शायद सबसे अच्छा उत्तर दो विधि है:

someMethod(stringParameter: string): void {
  this.someOtherMethod(0, stringParameter);
}

someOtherMethod(numberParameter: number, stringParameter: string): void {
  //...
}

यह आमतौर पर विधि अधिभार के रूप में नहीं जाना जाता है। प्रश्न भी देखें, पहले पैरामीटर का प्रकार बदलता है।
हकरे

3
मैंने स्वीकार किया कि मेरे उत्तर में - आप वैकल्पिक पैरामीटर को अंतिम रूप देंगे, इसलिए numberपैरामीटर दूसरा तर्क होगा और वैकल्पिक होगा। टाइपस्क्रिप्ट "उचित" विधि अधिभार का समर्थन नहीं करता है - लेकिन यहां तक ​​कि सी # दुनिया वैकल्पिक मापदंडों की ओर ओवरलोड से दूर जा रही है क्योंकि कई मामलों में यह अधिक पठनीय कोड की ओर जाता है।
फेंटन

आपका मतलब है if (typeof numberParameter != 'undefined'), ठीक है;)
जुआन मेंडेस

यह आपके उपयोग के मामले पर निर्भर करता है, विशेष रूप से कि क्या आप शून्य स्वीकार करते हैं। यदि आपको इसे करने की आवश्यकता है, तो !==जुगलबंदी से बचने के लिए उपयोग करना याद रखें ।
फेंटन

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

7

मैं चाहता हूँ। मैं यह सुविधा भी चाहता हूं, लेकिन टाइपस्क्रिप्ट को अनपेक्षित जावास्क्रिप्ट के साथ इंटरऑपरेबल होना चाहिए, जिसमें ओवरलोड तरीके नहीं हैं। यानी यदि आपकी ओवरलोड विधि को जावास्क्रिप्ट से पुकारा जाता है तो यह केवल एक विधि के कार्यान्वयन के लिए भेजा जा सकता है।

कोडप्लेक्स पर कुछ प्रासंगिक चर्चाएँ हैं। जैसे

https://typescript.codeplex.com/workitem/617

मुझे अभी भी लगता है कि टाइपस्क्रिप्ट को सभी if'ing और स्विचिंग उत्पन्न करनी चाहिए, इसलिए हमें ऐसा करने की आवश्यकता नहीं होगी।


2

वैकल्पिक संपत्ति परिभाषित इंटरफ़ेस का उपयोग क्यों न करेंफ़ंक्शन तर्क के रूप में ..

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

class TestClass {

    someMethod(arg: { stringParameter: string, numberParameter?: number }): void {
        let numberParameterMsg = "Variant #1:";
        if (arg.numberParameter) {
            numberParameterMsg = `Variant #2: numberParameter = ${arg.numberParameter},`;
        }
        alert(`${numberParameterMsg} stringParameter = ${arg.stringParameter}`);
    }
}

var testClass = new TestClass();
testClass.someMethod({ stringParameter: "string for v#1" });
testClass.someMethod({ numberParameter: 12345, stringParameter: "string for v#2" });

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

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


0

यदि विधि अधिभार के बहुत सारे रूपांतर हैं, तो दूसरा तरीका यह है कि आप अपने सभी आर्गों के साथ एक वर्ग बनाएं। इसलिए आप किसी भी क्रम में केवल वही पैरामीटर पास कर सकते हैं जो आप चाहते हैं।

class SomeMethodConfig {
  stringParameter: string;
  numberParameter: number;

 /**
 *
 */
 constructor(stringParameter: string = '012', numberParameter?: number) { // different ways to make a param optional
   this.numberParameter = 456; // you can put a default value here
   this.stringParameter = stringParameter; // to pass a value throw the constructor if necessary
 }
}

इसके अलावा, आप डिफ़ॉल्ट मानों और / या कुछ अनिवार्य तर्कों के साथ एक निर्माता बना सकते हैं। तो बस इस तरह का उपयोग करें:

const config = new SomeMethodConfig('text');
config.numberParameter = 123; // initialize an optional parameter only if you want to do it
this.SomeMethod(config);

-2

जावास्क्रिप्ट में ओवरलोडिंग की कोई अवधारणा नहीं है। टाइपस्क्रिप्ट c # या Java नहीं है।

लेकिन आप टाइपस्क्रिप्ट में ओवरलोडिंग को लागू कर सकते हैं।

इस पोस्ट को पढ़ें http://www.gyanparkash.in/function-overloading-in-typescript/


दुर्भाग्य से, लिंक टूट गया है। क्या आप रेपोस्ट कर सकते हैं?
एलएचएम

@ एलएमएच: इसीलिए लिंक-ओनली उत्तर हतोत्साहित किए जाते हैं।
डान डस्केल्सस्कू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.