টাইপস্ক্রিপ্ট ফাংশন ওভারলোডিং


242

টাইপস্ক্রিপ্ট ভাষা অনুচ্ছেদের Section.৩ অনুচ্ছেদে ফাংশন ওভারলোডিং সম্পর্কে কথা বলা হয়েছে এবং এটি কীভাবে বাস্তবায়ন করা যায় সে সম্পর্কে দৃ concrete় উদাহরণ দেয়। তবে আমি যদি এরকম কিছু চেষ্টা করি:

export class LayerFactory { 

    constructor (public styleFactory: Symbology.StyleFactory) { }

    createFeatureLayer (userContext : Model.UserContext, mapWrapperObj : MapWrapperBase) : any {           
         throw "not implemented";
    }                 

    createFeatureLayer(layerName : string, style : any) : any {
        throw "not implemented";
     }        

}

ফাংশন প্যারামিটারগুলি বিভিন্ন ধরণের হলেও ডুপ্লিকেট শনাক্তকারীকে নির্দেশ করে একটি সংকলক ত্রুটি পাই। এমনকি যদি আমি দ্বিতীয় ক্রিয়েটিফায়ার লাইয়ার ফাংশনে একটি অতিরিক্ত পরামিতি যুক্ত করি, তবুও আমি একটি সংকলক ত্রুটি পেয়েছি। ধারণা, দয়া করে।


উত্তর:


189

এটি কারণ হতে পারে, যখন উভয় ফাংশন জাভাস্ক্রিপ্টে সংকলিত হয়, তখন তাদের স্বাক্ষর সম্পূর্ণ অভিন্ন হয়। যেহেতু জাভাস্ক্রিপ্টের ধরণ নেই তাই আমরা দুটি সংখ্যক যুক্তি তৈরি করে শেষ করি। সুতরাং, টাইপস্ক্রিপ্ট আমাদের এ জাতীয় ফাংশন তৈরি করা থেকে বিরত রাখে।

টাইপসক্রিপ্ট প্যারামিটারের সংখ্যার ভিত্তিতে ওভারলোডিং সমর্থন করে, তবে আমরা ওও ভাষাগুলির সাথে তুলনা করলে অনুসরণ করা পদক্ষেপগুলি কিছুটা আলাদা। অন্য এসও প্রশ্নের উত্তরে কেউ একটি সুন্দর উদাহরণ দিয়ে ব্যাখ্যা করেছেন: পদ্ধতি ওভারলোডিং?

মূলত, আমরা যা করছি তা হ'ল, আমরা কেবল একটি ফাংশন এবং বেশ কয়েকটি ঘোষণা তৈরি করছি যাতে টাইপস্ক্রিপ্ট সংকলন ত্রুটি না দেয়। এই কোডটি জাভাস্ক্রিপ্টে সংকলিত হলে কংক্রিটের কাজটি একাই দৃশ্যমান হবে। যেমন একটি জাভাস্ক্রিপ্ট ফাংশন একাধিক যুক্তি পাস করে বলা যেতে পারে, এটি ঠিক কাজ করে।


50
এটি সমর্থন করার জন্য ভাষাটি সংশোধন করা যেতে পারে। তত্ত্ব অনুসারে, কেউ ফাংশন বাস্তবায়ন তৈরি করতে পারে যা আলাদা আলাদাভাবে সংকলিত টাইপসক্রিপ্ট (যেমন createFeatureLayer_1 এবং createFeatureLayer_2) দ্বারা কল করা হয় এবং createFeatureLayer তখন নির্ধারণ করতে পারে যে ভ্যানিলা জাভাস্ক্রিপ্টের সাথে আন্তঃব্যক্তির জন্য যুক্তির সামগ্রীর উপর ভিত্তি করে কোনটিকে কল করতে হবে to
থমাস এস ট্রায়াস

8
আপনি এটি শব্দটি লিখেছেন যেন টাইপস্ক্রিপ্টে ওভারলোডিং কেবলমাত্র পরামিতিগুলির সংখ্যার ভিত্তিতেই সম্ভব, যখন স্টিভ ফেন্টনের উত্তরে দেখানো হয়েছে টাইপের ভিত্তিতে ওভারলোডিংও সম্ভব।
ম্যাথিজ ওয়েজেলস

9
এটি এক ধরণের খোঁড়া; টাইপসক্রিপ্টটি সত্যই "মেটা ফাংশন" উত্পন্ন করা উচিত যা অনন্যভাবে নামকরণ বাস্তবায়ন উপযুক্তভাবে পাস হয়েছে তার ভিত্তিতে বেছে নেয়। এটি এখন কীভাবে এমন একটি ফাটল রয়েছে যেখানে আপনি সংকলকটি পাস করতে পারেন তবে আপনার ধরণের স্নিফিংয়ের প্রয়োগটি ভুল হতে পারে।
এজেকিয়েল ভিক্টর

5
@ রানহীন সময়ে প্রকারের পরীক্ষা করার কোনও নির্ভরযোগ্য উপায় থাকলে @ ইজিকেলভিক্টর টাইপস্ক্রিপ্ট এটি করবে।
কাঁটা

3
এটি আরও জটিল, এটি জাভাস্ক্রিপ্টের ধরণের সাথে কার্যকর, তবে টিএস-নির্দিষ্ট ধারণা যেমন ইন্টারফেস, typeগুলি, এনামস, জেনেরিকস, ইত্যাদি রানটাইমের সময় হারিয়ে যায়। এজন্যই আপনি করতে পারবেন না someObject instanceof ISomeInterfaceDefinedInTypeScript
মরগান টোভেরি কুইলিং

209

আপনি যখন টাইপস্ক্রিপ্টে ওভারলোড করেন, আপনার একাধিক স্বাক্ষর সহ কেবলমাত্র একটি বাস্তবায়ন থাকে।

class Foo {
    myMethod(a: string);
    myMethod(a: number);
    myMethod(a: number, b: string);
    myMethod(a: any, b?: string) {
        alert(a.toString());
    }
}

প্রকৃত বাস্তবায়ন নয়, কেবলমাত্র তিনটি ওভারলোডগুলি কোনও পদ্ধতি কলের জন্য স্বাক্ষর হিসাবে টাইপস্ক্রিপ্ট দ্বারা স্বীকৃত।

আপনার ক্ষেত্রে, আমি ব্যক্তিগতভাবে পৃথক নাম সহ দুটি পদ্ধতি ব্যবহার করব কারণ প্যারামিটারগুলিতে পর্যাপ্ত পরিমাণে সাধারণতা নেই, যার ফলে এটি করার সিদ্ধান্ত নেওয়ার জন্য পদ্ধতিটির শরীরের প্রচুর "ifs" লাগবে likely

প্রকারলিপি 1.4

টাইপস্ক্রিপ্ট ১.৪ হিসাবে, আপনি সাধারণত ইউনিয়নের ধরণ ব্যবহার করে ওভারলোডের প্রয়োজনীয়তা সরাতে পারেন। উপরের উদাহরণটি আরও ভালভাবে ব্যবহার করে প্রকাশ করা যেতে পারে:

myMethod(a: string | number, b?: string) {
    alert(a.toString());
}

প্রকারটি a"হয় stringবা number" হয়।


দুর্দান্ত উত্তর। আমি কেবল এটি হাইলাইট করতে চাই, যখন কেউ অতিরিক্ত কারণে বোঝার চেষ্টা করছে যেমন এর কারণ হতে পারে: যেমন একটি কনস্ট্রাক্টর ব্যবহার করে আমি একটি উদাহরণ পেতে চাই, যেখানে আমি সমস্ত প্রত্যাশিত বৈশিষ্ট্য সংজ্ঞায়িত করে একটি বস্তুটি পাস করতে পারি এক উদাহরণ, স্বতন্ত্র class Foo { constructor(obj) { } constructor (a: number, b: string, c: boolean) {} }
প্যারামগুলি

সাধারণভাবে, আমি বরং প্রতিটি উপায়ে আমাকে একটি অবজেক্ট তৈরি করার জন্য একটি কারখানার পদ্ধতি ব্যবহার করতাম - আপনি কল করেন Foo.fromObject(obj)এবং অন্যভাবে ডায়াল করার দরকার নেই Foo.fromJson(str)
ফেন্টন

তবে এটি পোস্টুলেট করে যে যে কোনও একটি বস্তু বা একটি একক স্ট্রিং হিসাবে সর্বদা তাদের পরামিতিগুলি পাস করবে, আমার পূর্ববর্তী মন্তব্য থেকে হাইলাইট করে আমি যদি সেগুলি আলাদাভাবে পাস করতে চাই তবে কী হবে? Foo.methos(1, 2, 3) Foo.method(1) Foo.method(Obj) আমি আরও লক্ষ্য করেছি যে Fooক্লাসে আপনার বিভিন্ন পদ্ধতি রয়েছে , অফজেক্ট এবং জসন থেকে?
হালাউলেকা এমএএস

1
যদি আপনি সেই পার্থক্যটি উত্সটিতে ফিরে যান তবে আপনি সাধারণত দেখতে পাবেন যে এর কোনও প্রয়োজন নেই। উদাহরণস্বরূপ, আপনাকে টাইপ করতে হবে myNumবা myObjযাহাই হউক না কেন, তবে কেন আলাদা পদ্ধতি না রেখে সমস্ত কিছু পরিষ্কার করা / অপ্রয়োজনীয় ব্রাঞ্চিং যুক্তি এড়ানো উচিত নয়।
ফেন্টন

2
নোট করুন যে ইউনিয়নের ধরণটি ব্যবহার করা সমস্যাযুক্ত হতে পারে যদি আপনি প্যারামিটারগুলির উপর ভিত্তি করে ভিন্ন ভিন্ন রিটার্ন পেতে চান। এটি জেনেরিকের সাথে সমাধান করা যেতে পারে যদি রিটার্ন টাইপ সর্বদা প্যারামিটার ধরণের কোনওটির সাথে মেলে তবে অন্যান্য ক্ষেত্রে ওভারলোডগুলি সর্বোত্তম সমাধান।
জন মন্টগোমেরি

45

আপনি করতে পারেন ডিক্লেয়ার একটি টাইপ একাধিক আবাহন স্বাক্ষর হয়েছে তার হিসাবে ফাংশন ঘোষণা করে একটি ওভারলোড ফাংশন:

interface IFoo
{
    bar: {
        (s: string): number;
        (n: number): string;
    }
}

তারপরে নিম্নলিখিত:

var foo1: IFoo = ...;

var n: number = foo1.bar('baz');     // OK
var s: string = foo1.bar(123);       // OK
var a: number[] = foo1.bar([1,2,3]); // ERROR

ফাংশনটির আসল সংজ্ঞাটি একক হতে হবে এবং এর তর্কগুলিতে অভ্যন্তরীণভাবে উপযুক্ত প্রেরণ করতে হবে perform

উদাহরণস্বরূপ, একটি শ্রেণি ব্যবহার করে (যা বাস্তবায়ন করতে পারে IFooতবে তা করতে হবে না):

class Foo
{
    public bar(s: string): number;
    public bar(n: number): string;
    public bar(arg: any): any 
    {
        if (typeof(arg) === 'number')
            return arg.toString();
        if (typeof(arg) === 'string')
            return arg.length;
    }
}

এখানে আকর্ষণীয় বিষয়টি হ'ল anyফর্মটি আরও নির্দিষ্টভাবে টাইপ করা ওভাররাইড দ্বারা লুকানো থাকে

var foo2: new Foo();

var n: number = foo2.bar('baz');     // OK
var s: string = foo2.bar(123);       // OK
var a: number[] = foo2.bar([1,2,3]); // ERROR

1

সাধারণভাবে ফাংশন ওভারলোডিং কী?

ফাংশন ওভারলোডিং বা পদ্ধতি ওভারলোডিং তৈরি করার ক্ষমতা নেই একাধিক ফাংশন এর একই নামের সঙ্গে বিভিন্ন বাস্তবায়নের ( উইকিপিডিয়া )


জেএসে ফাংশন ওভারলোডিং কী?

এই বৈশিষ্ট্যটি জেএসে সম্ভব নয় - একাধিক ঘোষণার ক্ষেত্রে শেষ সংজ্ঞায়িত ফাংশনটি নেওয়া হয়:

function foo(a1, a2) { return `${a1}, ${a2}` }
function foo(a1) { return `${a1}` } // replaces above `foo` declaration
foo(42, "foo") // "42"

... এবং টিএসে?

জেএস রানটাইমটিতে কোনও প্রভাব ছাড়াই ওভারলোডগুলি একটি সংকলন-সময় নির্মাণ:

function foo(s: string): string // overload #1 of foo
function foo(s: string, n: number): number // overload #2 of foo
function foo(s: string, n?: number): string | number {/* ... */} // foo implementation

যদি আপনি উপরের কোডটি ব্যবহার করেন (জেএস এর চেয়ে নিরাপদ) তবে একটি সদৃশ প্রয়োগের ত্রুটি ট্রিগার করা হয়। টিএস টপ-ডাউন ক্রমে প্রথম ফিটিং ওভারলোড চয়ন করে, তাই ওভারলোডগুলি সুনির্দিষ্ট থেকে সবচেয়ে বিস্তৃত অনুসারে বাছাই করা হয়।


টিএসে পদ্ধতি ওভারলোডিং: আরও জটিল উদাহরণ

অতিরিক্ত লোড শ্রেণীর পদ্ধতির প্রকারগুলি ওভারলোডিং কার্য করতে একই পদ্ধতিতে ব্যবহার করা যেতে পারে:

class LayerFactory {
    createFeatureLayer(a1: string, a2: number): string
    createFeatureLayer(a1: number, a2: boolean, a3: string): number
    createFeatureLayer(a1: string | number, a2: number | boolean, a3?: string)
        : number | string { /*... your implementation*/ }
}

const fact = new LayerFactory()
fact.createFeatureLayer("foo", 42) // string
fact.createFeatureLayer(3, true, "bar") // number

বিস্তৃত বিভিন্ন ওভারলোডগুলি সম্ভব, কারণ ফাংশন বাস্তবায়ন সমস্ত ওভারলোড স্বাক্ষরের সাথে সামঞ্জস্যপূর্ণ - সংকলক দ্বারা প্রয়োগ করা হয়।

আরও ইনফো


0

অন্যের কাছে প্রধান হিসাবে, আমি অবলম্বন করেছি যে কমপক্ষে 2 জন্য ওয়েবপ্যাক দ্বারা সংকলিত টাইপস্ক্রিপ্ট দ্বারা প্রকাশিত হয়েছে, আপনি চুপচাপ ওভারল্যাড পদ্ধতির পরিবর্তে ওভাররাইটেন পাবেন।

myComponent {
  method(): { console.info("no args"); },
  method(arg): { console.info("with arg"); }
}

কল করা হচ্ছে:

myComponent.method()

আউটপুট সহ নো-আরগ সংস্করণটি চুপচাপ উপেক্ষা করে আর্গুমেন্টগুলি সহ পদ্ধতিটি কার্যকর করে দেখা যাচ্ছে:

with arg

2
আপনি আপনার ওভারলোডগুলির জন্য পৃথক সংস্থা ঘোষণা করতে পারবেন না, কেবল ভিন্ন স্বাক্ষর।
adharris

5
আপনি টাইপস্ক্রিপ্ট সংকলনের কোন সংস্করণটি ব্যবহার করছেন তা আমি নিশ্চিত নই, তবে বর্তমান সংস্করণটি Duplicate function implementationএই জাতীয় কোডের জন্য একটি সতর্কতা প্রকাশ করে।
রয়স্টন শুফলবোথাম

0

টাইপস্ক্রিপ্টে ফাংশন ওভারলোডিং:

উইকিপিডিয়া অনুসারে, (এবং অনেক প্রোগ্রামিং বই) পদ্ধতি / ফাংশন ওভারলোডিংয়ের সংজ্ঞাটি নিম্নলিখিত:

কিছু প্রোগ্রামিং ভাষায়, ফাংশন ওভারলোডিং বা পদ্ধতি ওভারলোডিং হ'ল বিভিন্ন বাস্তবায়ন সহ একই নামের একাধিক ফাংশন তৈরির ক্ষমতা । একটি ওভারলোডেড ফাংশনটির কলগুলি কলটির প্রসঙ্গে উপযুক্ত সেই ফাংশনের একটি নির্দিষ্ট বাস্তবায়ন পরিচালনা করে, যা একটি ফাংশন কলকে প্রসঙ্গে নির্ভর করে বিভিন্ন কার্য সম্পাদন করতে দেয়।

টাইপস্ক্রিপ্টে আমাদের একই ক্রিয়াকলাপের বিভিন্ন বাস্তবায়ন থাকতে পারে না যা আর্গুমেন্টের সংখ্যা এবং ধরণ অনুযায়ী ডাকা হয়। এটি কারণ যখন টিএস জেএসে সংকলিত হয়, জেএসের ফাংশনগুলির নিম্নলিখিত বৈশিষ্ট্য থাকে:

  • জাভাস্ক্রিপ্ট ফাংশন সংজ্ঞা তাদের পরামিতিগুলির জন্য ডেটা ধরণের নির্দিষ্ট করে না
  • জাভাস্ক্রিপ্ট ফাংশন কল করার সময় আর্গুমেন্টের সংখ্যা পরীক্ষা করে না

অতএব, কঠোর অর্থে, কেউ যুক্তি দিতে পারেন যে টিএস ফাংশন ওভারলোডিংয়ের অস্তিত্ব নেই। তবে, আপনার টিএস কোডের মধ্যে এমন কিছু জিনিস রয়েছে যা পুরোপুরি ফাংশন ওভারলোডিংকে নকল করতে পারে।

এখানে একটি উদাহরণ:

function add(a: number, b: number, c: number): number;
function add(a: number, b: number): any;
function add(a: string, b: string): any;

function add(a: any, b: any, c?: any): any {
  if (c) {
    return a + c;
  }
  if (typeof a === 'string') {
    return `a is ${a}, b is ${b}`;
  } else {
    return a + b;
  }
}

টিএস ডক্সটি এই পদ্ধতিটিকে ওভারলোডিং বলে we সংকলনের সময় আমরা আমাদের ফাংশনটিকে সঠিকভাবে ডেকেছি এবং টিউনটি ভুলভাবে ফাংশনটি কল করলে আমাদের একটি ত্রুটি দেয় কিনা তা এখন টিএস সনাক্ত করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.