TypeScript মধ্যে কনস্ট্রাক্টর ওভারলোড




constructor overloading (7)

টাইপস্ক্রিপ্টে কেউ কি কনস্ট্রাক্টর ওভারলোডিং করেছে। ভাষা স্পেসিফিকেশন পৃষ্ঠার 64 পৃষ্ঠায় (ভি 0.8), কন্সট্রাকটর ওভারলোডগুলি বর্ণনাকারী বিবৃতি রয়েছে, তবে কোন নমুনা কোড দেওয়া হয়নি।

আমি এখন একটি সত্যিই মৌলিক বর্গ ঘোষণা আউট চেষ্টা করছি; এটা দেখে মনে হচ্ছে,

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 দিয়ে দৌড়ে যায়, এটি একটি সদৃশ কনস্ট্রাক্টর সংজ্ঞা ছুঁড়ে ফেলে - যা সুস্পষ্ট। কোন সাহায্য প্রশংসা করা হয়।


@ শিননোওনির কোডের মতো অন্য সংস্করণটি ডিফল্ট মানগুলি ব্যবহার করে এবং সিন্ট্যাক্স ছড়িয়ে দেয়:

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

আপনি এই দ্বারা পরিচালনা করতে পারেন:

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

আংশিক আপনার ক্ষেত্র (এক্স, Y, উচ্চতা, প্রস্থ) বিকল্পগুলি তৈরি করবে, একাধিক কন্সট্রাক্টরকে অনুমতি দেবে

উদাহরণস্বরূপ: আপনি new Box({x,y}) উচ্চতা ছাড়াই এবং প্রস্থ করতে পারেন।

= {} ফালসির মান হ্যান্ডেল করবে যেমন অনির্ধারিত, নাল ইত্যাদি, এবং তারপর আপনি new Box() করতে পারেন new Box()


আমি জানি এটি একটি পুরানো প্রশ্ন, তবে নতুন 1.4 টি ইউনিয়ন ধরনের; সমস্ত ফাংশন overloads (কন্সট্রাকটর সহ) জন্য এই ব্যবহার করুন। উদাহরণ:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);

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

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 অনুসারে, আরও বিস্তৃত সমাধানের জন্য বেনসনের উত্তরটি দেখুন যা আরও নমনীয়তা দেয়।


টাইপস্ক্রিপ্ট আপনাকে ওভারলোডগুলি ঘোষণা করার অনুমতি দেয় তবে আপনার কেবলমাত্র একটি বাস্তবায়ন থাকতে পারে এবং যে প্রয়োগটির সমস্ত ওভারলোডগুলির সাথে সামঞ্জস্যপূর্ণ একটি স্বাক্ষর থাকতে হবে। আপনার উদাহরণে, এটি সহজেই একটি ঐচ্ছিক প্যারামিটারের সাথে সম্পন্ন করা যেতে পারে,

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

নোট: এটি সরলীকৃত এবং টাইপস্ক্রিপ্ট 2.1 প্রতিফলিত করতে 4/13/2017 আপডেট করা হয়েছে, TypeScript 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 Box class can work double-duty as the interface here since they are identical
     // If you choose to add methods or modify this class, you will need to
     // define and reference a new interface for the incoming parameters object 
     // e.g.:  `constructor(params: BoxObjI = {} as BoxObjI)` 
     constructor(params: Box = {} as Box) {

         // Define the properties of the incoming `params` object here. 
         // Setting a default value with the `= 0` syntax is optional for each parameter
         let {
             x = 0,
             y = 0,
             height = 1,
             width = 1
         } = params;

         //  If needed, make the parameters publicly accessible
         //  on the class ex.: 'this.var = var'.
         /**  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; var = isOptional || default; void 0 জন্য শর্ট্যান্ড হয় যা void 0 বিরুদ্ধে চেক করে:

কম্পাইল আউটপুট

var Box = (function () {
    function Box(params) {
        if (params === void 0) { params = {}; }
        var _a = params.x, x = _a === void 0 ? 0 : _a, _b = params.y, y = _b === void 0 ? 0 : _b, _c = params.height, height = _c === void 0 ? 1 : _c, _d = params.width, width = _d === void 0 ? 1 : _d;
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
    }
    return Box;
}());

সংযোজন: ডিফল্ট মান নির্ধারণ: ভুল উপায়

|| (বা) অপারেটর

এর বিপদ বিবেচনা করুন || / অথবা অপারেটর ডিফল্ট fallback মান নির্ধারণ করার সময় অন্য কিছু উত্তর দেখানো। নীচের এই কোড ডিফল্ট সেট ভুল উপায় illustrates। 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 (এই, প্যারাম)

আমার পরীক্ষায়, es6 / টাইপসक्रिप्ट ধ্বংসাত্মক বস্তু ব্যবহার করে বস্তু। অ্যাসাইনের চেয়ে প্রায় 90% দ্রুত হতে পারে । একটি বিধ্বংসী পরামিতি ব্যবহার করে শুধুমাত্র আপনি বস্তুর বরাদ্দ করা পদ্ধতি এবং বৈশিষ্ট্য অনুমতি দেয়। উদাহরণস্বরূপ, এই পদ্ধতি বিবেচনা করুন:

class BoxTest {
    public x?: number = 1;

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

যদি অন্য ব্যবহারকারী টাইপস্ক্রিপ্ট ব্যবহার করে না এবং এমন কোনও প্যারামিটার স্থাপন করার চেষ্টা করে যা বলে না, তবে তারা একটি 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 params.
console.assert(typeof box.z === 'undefined')

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

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

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





overloading