টাইপস্ক্রিপ্ট এবং ক্ষেত্রের সূচনা


251

কীভাবে TSএইভাবে একটি নতুন ক্লাস শুরু করা যায় (উদাহরণস্বরূপ C#আমি কী চাই তা দেখানোর জন্য):

// ... some code before
return new MyClass { Field1 = "ASD", Field2 = "QWE" };
// ...  some code after

[সম্পাদনা]
আমি যখন এই প্রশ্নটি লিখছিলাম তখন আমি খাঁটি ছিলাম। জেএসের বেশি জ্ঞান ছাড়াই নেট বিকাশকারী। এছাড়াও টাইপস্ক্রিপ্ট সম্পূর্ণ নতুন কিছু ছিল, জাভাস্ক্রিপ্টের নতুন সি # ভিত্তিক সুপারসেট হিসাবে ঘোষণা করা হয়েছিল। আজ আমি দেখছি এই প্রশ্নটি কতটা বোকা ছিল।

যাইহোক কেউ যদি এখনও কোনও উত্তর খুঁজছেন, দয়া করে নীচের সম্ভাব্য সমাধানগুলি দেখুন।

টিএস-এ প্রথম লক্ষণীয় জিনিসটি আমাদের মডেলগুলির জন্য খালি ক্লাস তৈরি করা উচিত নয়। ইন্টারফেস বা টাইপ (প্রয়োজনের উপর নির্ভর করে) তৈরি করা ভাল উপায়। টড মোটো থেকে ভাল নিবন্ধ: https://ultimatecourses.com/blog/classes-vs-interfaces-in-typescript

সমাধান 1:

type MyType = { prop1: string, prop2: string };

return <MyType> { prop1: '', prop2: '' };

সমাধান 2:

type MyType = { prop1: string, prop2: string };

return { prop1: '', prop2: '' } as MyType;

সমাধান 3 (যখন আপনার সত্যিকার অর্থে ক্লাসের প্রয়োজন হবে):

class MyClass {
   constructor(public data: { prop1: string, prop2: string }) {}
}
// ...
return new MyClass({ prop1: '', prop2: '' });

অথবা

class MyClass {
   constructor(public prop1: string, public prop2: string) {}
}
// ...
return new MyClass('', '');

অবশ্যই উভয় ক্ষেত্রে ম্যানুয়ালি আপনার castালাই ধরণের প্রয়োজন হতে পারে না কারণ সেগুলি ফাংশন / পদ্ধতি রিটার্ন টাইপ থেকে সমাধান করা হবে।


9
আপনি কেবল আপনার প্রশ্নের সাথে যুক্ত "সমাধান" বৈধ টাইপস্ক্রিপ্ট বা জাভাস্ক্রিপ্ট নয়। তবে এটি উল্লেখ করা মূল্যবান যে এটি চেষ্টা করা সবচেয়ে স্বজ্ঞাত জিনিস।
— জ্যাকব ফশি

1
@ জ্যাকবফোশি বৈধ জাভাস্ক্রিপ্ট না? আমার Chrome দেব সরঞ্জামসমূহ দেখুন: i.imgur.com/vpathu6.png (কিন্তু ভিসুয়াল স্টুডিও কোড বা অন্য কোন টাইপ করা বিষয় linted অবশ্যম্ভাবীরূপে অভিযোগ হবে)
— মঙ্গল রবার্টসন

5
আমি মন্তব্যটি পোস্ট করার পরে @ মিশালস্টেফানো ওপি প্রশ্নটি সম্পাদনা করেছেন। তার কাছে রয়েছেreturn new MyClass { Field1: "ASD", Field2: "QWE" };
— জ্যাকব ফোশি

উত্তর:


90

হালনাগাদ

এই উত্তরটি লেখার পর থেকে আরও ভাল উপায় উঠে এসেছে। দয়া করে নীচের অন্যান্য উত্তরগুলি দেখুন যার আরও বেশি ভোট এবং আরও ভাল উত্তর রয়েছে। আমি এই উত্তরটিকে গ্রহণযোগ্য হিসাবে চিহ্নিত করার কারণে এটি অপসারণ করতে পারি না।


পুরানো উত্তর

টাইপস্ক্রিপ্ট কোডপ্লেক্সে একটি সমস্যা রয়েছে যা এটি বর্ণনা করে: অবজেক্ট আরম্ভকারীদের জন্য সমর্থন ।

যেমন বলা হয়েছে, আপনি ক্লাসের পরিবর্তে টাইপস্ক্রিপ্টে ইন্টারফেস ব্যবহার করে এটি ইতিমধ্যে করতে পারেন:

interface Name {
    first: string;
    last: string;
}
class Person {
    name: Name;
    age: number;
}

var bob: Person = {
    name: {
        first: "Bob",
        last: "Smith",
    },
    age: 35,
};

81
আপনার উদাহরণে, বব কোনও ব্যক্তি শ্রেণীর উদাহরণ নয়। আমি দেখতে পাচ্ছি না কীভাবে এটি সি # উদাহরণের সমান।
— জ্যাক ওয়েস্টার

3
"I" মূলধন দিয়ে ইন্টারফেসের নামগুলি শুরু করা ভাল
— কিয়ারাশ

16
1. ব্যক্তি কোনও শ্রেণি নয় এবং ২। @ জ্যাক ওয়েস্টার ঠিক আছে, বব কোনও ব্যক্তি নয় instance সতর্কতা চেষ্টা করুন (ব্যক্তি বব উদাহরণস্বরূপ); এই কোডটিতে ব্যক্তি কেবলমাত্র টাইপ-এ্যাসারেশন উদ্দেশ্যে রয়েছে।
— জ্যাক

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

26
কেন এটি স্বীকৃত উত্তর যখন এটি স্পষ্টত ভুল?
— হেনড্রিক উইস

447

07/12/2016 আপডেট হয়েছে: টাইপসক্রিপ্ট 2.1 ম্যাপযুক্ত প্রকারগুলি সরবরাহ করে এবং সরবরাহ করে Partial<T>, যা আপনাকে এটি করতে দেয় ...

class Person {
    public name: string = "default"
    public address: string = "default"
    public age: number = 0;

    public constructor(init?:Partial<Person>) {
        Object.assign(this, init);
    }
}

let persons = [
    new Person(),
    new Person({}),
    new Person({name:"John"}),
    new Person({address:"Earth"}),    
    new Person({age:20, address:"Earth", name:"John"}),
];

আসল উত্তর:

আমার পদ্ধতির একটি পৃথক fieldsভেরিয়েবল সংজ্ঞায়িত করা হয় যা আপনি কনস্ট্রাক্টরের কাছে পাস করেন। কৌশলটি হ'ল initialচ্ছিক হিসাবে এই আরম্ভকারীটির জন্য সমস্ত শ্রেণীর ক্ষেত্রকে নতুনভাবে সংজ্ঞায়িত করা। যখন অবজেক্টটি তৈরি করা হয় (এর ডিফল্টগুলি দিয়ে) আপনি কেবলমাত্র আরম্ভকারী বস্তুটি এর উপর নির্ধারণ করেন this;

export class Person {
    public name: string = "default"
    public address: string = "default"
    public age: number = 0;

    public constructor(
        fields?: {
            name?: string,
            address?: string,
            age?: number
        }) {
        if (fields) Object.assign(this, fields);
    }
}

অথবা এটি ম্যানুয়ালি করুন (আরও নিরাপদ):

if (fields) {
    this.name = fields.name || this.name;       
    this.address = fields.address || this.address;        
    this.age = fields.age || this.age;        
}

ব্যবহার:

let persons = [
    new Person(),
    new Person({name:"Joe"}),
    new Person({
        name:"Joe",
        address:"planet Earth"
    }),
    new Person({
        age:5,               
        address:"planet Earth",
        name:"Joe"
    }),
    new Person(new Person({name:"Joe"})) //shallow clone
]; 

এবং কনসোল আউটপুট:

Person { name: 'default', address: 'default', age: 0 }
Person { name: 'Joe', address: 'default', age: 0 }
Person { name: 'Joe', address: 'planet Earth', age: 0 }
Person { name: 'Joe', address: 'planet Earth', age: 5 }
Person { name: 'Joe', address: 'default', age: 0 }   

এটি আপনাকে প্রাথমিক সুরক্ষা এবং সম্পত্তির সূচনা দেয়, তবে এটি সমস্ত alচ্ছিক এবং আদেশের বাইরে চলে যেতে পারে। আপনি যদি কোনও ক্ষেত্রটি পাস না করেন তবে আপনি ক্লাসের ডিফল্টগুলি একা পেয়ে যাবেন।

আপনি এটি প্রয়োজনীয় কন্সট্রাক্টর পরামিতিগুলির সাথেও মিশ্রিত করতে পারেন - শেষটি fieldsআটকে দিন।

সি # স্টাইলের যত কাছাকাছি আপনি যতটা ভাবতে চলেছেন ( আসল ফিল্ড-ইন সিনট্যাক্স প্রত্যাখ্যান করা হয়েছিল) )। আমি অনেকটা যথাযথ ফিল্ড ইনিশিয়ালাইজারকে পছন্দ করি, তবে এটি এখনও ঘটবে বলে মনে হয় না।

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


1
+1 টি। এটি আসলে একটি শ্রেণীর উদাহরণ তৈরি করে (যা বেশিরভাগ সমাধানগুলি সমাধান করে না), কনস্ট্রাক্টরের ভিতরে সমস্ত কার্যকারিতা রাখে (কোনও অবজেক্ট.ক্রিয়েট বা অন্য ক্রাফ্টের বাইরে নেই), এবং স্পষ্টভাবে সম্পত্তি নামটি পরম ক্রমের উপর নির্ভর করার পরিবর্তে উল্লেখ করে ( আমার ব্যক্তিগত পছন্দ এখানে)। যদিও এটি প্যারাম এবং বৈশিষ্ট্যগুলির মধ্যে টাইপ / সংকলন সুরক্ষা হারাবে না।
— ফিডলস

1
@ ব্যবহারকারী 1817787 আপনি সম্ভবত ক্লাসে alচ্ছিক হিসাবে কোনও ডিফল্ট রয়েছে এমন কোনও কিছু সংজ্ঞায়িত করার চেয়ে ভাল, তবে একটি ডিফল্ট নির্ধারণ করুন। তারপরে Partial<>কেবল ব্যবহার করবেন না Person- এর জন্য আপনাকে প্রয়োজনীয় ক্ষেত্র রয়েছে এমন একটি বস্তু পাস করতে হবে। যা বলেছিল, এমন ধারণাগুলির জন্য এখানে দেখুন (চয়ন করুন দেখুন) যা নির্দিষ্ট ক্ষেত্রের মধ্যে টাইপ ম্যাপিংকে সীমাবদ্ধ করে।
— মেরিওন হিউজেস

2
এটি সত্যই উত্তর হওয়া উচিত। এটি এই সমস্যার সেরা সমাধান।
— Ascherer

9
সেটি হল গোল্ডেন কোডের টুকরোpublic constructor(init?:Partial<Person>) { Object.assign(this, init); }
— কুনসেভিক.দেব

3
যদি অবজেক্ট.সেসাইনটি আমার জন্য এটির মতো ত্রুটি দেখিয়ে চলেছে তবে দয়া করে এই এসও উত্তরটি দেখুন: stackoverflow.com/a/38860354/2621693
— জিম ইয়ারব্রো

27

নীচে এমন একটি সমাধান দেওয়া হয়েছে যা Object.assignআরও নিবিড়ভাবে মূল C#প্যাটার্নটির মডেল করার জন্য একটি সংক্ষিপ্ত প্রয়োগকে একত্রিত করে।

তবে প্রথমে, এখন পর্যন্ত দেওয়া কৌশলগুলি পর্যালোচনা করা যাক যার মধ্যে রয়েছে:

  1. অনুলিপি নির্মাণকারী যারা কোনও বস্তু গ্রহণ করে এবং এটি প্রয়োগ করে Object.assign
  2. Partial<T>অনুলিপি নির্মাণকারীর মধ্যে একটি চতুর কৌশল
  3. কোনও পজোর বিরুদ্ধে "ingালাই" ব্যবহার
  4. Object.createপরিবর্তে লাভারেজিংObject.assign

অবশ্যই, প্রত্যেকের পক্ষে তাদের পক্ষে ভাল / বিপরীত রয়েছে। একটি অনুলিপি নির্মাণকারী একটি লক্ষ্য বর্গ পরিবর্তন করা সর্বদা একটি বিকল্প হতে পারে না। এবং "ingালাই" লক্ষ্য প্রকারের সাথে সম্পর্কিত কোনও ফাংশন হারায়। Object.createএর চেয়ে কম আবেদনকারী বলে মনে হচ্ছে যেহেতু এটির পরিবর্তে ভার্বোস সম্পত্তি বর্ণনাকারী মানচিত্রের প্রয়োজন।

সংক্ষিপ্ততম, সাধারণ-উদ্দেশ্য উত্তর

সুতরাং, এখানে আরও একটি পদ্ধতির যা কিছুটা সহজ, প্রকারের সংজ্ঞা এবং সম্পর্কিত ফাংশন প্রোটোটাইপগুলি বজায় রাখে, এবং আরও নিবিড়ভাবে নকশাকৃত নকশাকে মডেল করে C#:

const john = Object.assign( new Person(), {
    name: "John",
    age: 29,
    address: "Earth"
});

এটাই. C#প্যাটার্নটিতে কেবলমাত্র সংযোজনটি Object.assign2 বন্ধনী এবং একটি কমা সহ। এটি ধরণের ফাংশন প্রোটোটাইপগুলি বজায় রাখে তা নিশ্চিত করতে নীচের কার্যকারী উদাহরণটি দেখুন। কোন নির্মাণকারীর প্রয়োজন নেই, এবং কোনও চালাক কৌশল নয় ricks

কাজের উদাহরণ

এই উদাহরণটি দেখায় কীভাবে কোনও C#ক্ষেত্র আরম্ভকারীর সান্নিধ্য ব্যবহার করে কোনও বস্তুর সূচনা করতে হবে:

class Person {
    name: string = '';
    address: string = '';
    age: number = 0;

    aboutMe() {
        return `Hi, I'm ${this.name}, aged ${this.age} and from ${this.address}`;
    }
}

// typescript field initializer (maintains "type" definition)
const john = Object.assign( new Person(), {
    name: "John",
    age: 29,
    address: "Earth"
});

// initialized object maintains aboutMe() function prototype
console.log( john.aboutMe() );


এটির মতো, জাভাস্ক্রিপ্ট অবজেক্ট থেকে একটি ব্যবহারকারী অবজেক্ট তৈরি করতে পারেন
— ডেভ কেইন

1
6½ বছর পরে আমি এটি ভুলে গিয়েছিলাম, তবে আমি এখনও এটি পছন্দ করি। আবার ধন্যবাদ.
— PRMan

25

আপনি আপনার শ্রেণীর ধরণে ছড়িয়ে থাকা কোনও বেনামে জিনিসকে প্রভাবিত করতে পারেন। বোনাস : ভিজ্যুয়াল স্টুডিওতে, আপনি এভাবে ইন্টেলিজেন্সের সুবিধা পাবেন :)

var anInstance: AClass = <AClass> {
    Property1: "Value",
    Property2: "Value",
    PropertyBoolean: true,
    PropertyNumber: 1
};

সম্পাদনা:

সতর্কতামূলক যদি ক্লাসের পদ্ধতি থাকে তবে আপনার শ্রেণীর উদাহরণ এগুলি পাবেন না। যদি AClass এর কোন কনস্ট্রাক্টর থাকে তবে এটি কার্যকর করা হবে না। আপনি যদি AClass ব্যবহার করেন তবে আপনি মিথ্যা পাবেন।

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

interface IModel {
   Property1: string;
   Property2: string;
   PropertyBoolean: boolean;
   PropertyNumber: number;
}

var anObject: IModel = {
     Property1: "Value",
     Property2: "Value",
     PropertyBoolean: true,
     PropertyNumber: 1
 };

20
যদি AClassপদ্ধতি থাকে anInstanceতবে সেগুলি পেত না।
— মনসাইনর

2
এছাড়াও AClass এর যদি কনস্ট্রাক্টর থাকে তবে এটি কার্যকর করা হবে না।
— মাইকেল এরিকসন

1
এছাড়াও যদি আপনি এটি করেন রানটাইম এ anInstance instanceof AClassপাবেন false।
— Lucero

15

আমি এমন একটি পদ্ধতির পরামর্শ দিচ্ছি যাতে টাইপস্ক্রিপ্ট ২.১ প্রয়োজন হয় না:

class Person {
    public name: string;
    public address?: string;
    public age: number;

    public constructor(init:Person) {
        Object.assign(this, init);
    }

    public someFunc() {
        // todo
    }
}

let person = new Person(<Person>{ age:20, name:"John" });
person.someFunc();

গুরুত্বপূর্ণ দিক:

  • টাইপস্ক্রিপ্ট 2.1 প্রয়োজন হয় Partial<T>না, প্রয়োজন হয় না
  • এটি ফাংশনগুলি সমর্থন করে (সাধারণ ধরণের দৃser়তার সাথে তুলনা করে যা কার্যগুলি সমর্থন করে না)

1
এটি বাধ্যতামূলক ক্ষেত্রগুলিকে সম্মান করে না: new Person(<Person>{});(কারণ castালাই করা) এবং খুব পরিষ্কার হওয়াও; আংশিক <T> ব্যবহার করে ফাংশন সমর্থন করে। শেষ পর্যন্ত, আপনার যদি ক্ষেত্রগুলির প্রয়োজন হয় (প্লাস প্রোটোটাইপ ফাংশন) আপনার করতে হবে: init: { name: string, address?: string, age: number }এবং castালাই বাদ দিন।
— মেরিওন হিউজেস

এছাড়াও যখন আমরা শর্তযুক্ত প্রকারের ম্যাপিং পাই তখন আপনি কেবলমাত্র ফাংশনগুলিকে পার্টিয়ালগুলিতে ম্যাপ করতে এবং বৈশিষ্ট্যগুলি যেমন রাখবেন তেমন সক্ষম হবেন। :)
— মিরিওন হিউজেস

পরিশীলিতের classপরিবর্তে var, যদি আমি করি তবে var dog: {name: string} = {name: 'will be assigned later'};এটি সংকলন করে এবং কাজ করে। কোন ঘাটতি বা ইস্যু? ওহ, dogখুব ছোট সুযোগ এবং নির্দিষ্ট আছে, যার অর্থ শুধুমাত্র একটি উদাহরণ।
— Jeb50

11

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

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

class MyClass{
    constructor(public Field1:string = "", public Field2:string = "")
    {
        // other constructor stuff
    }
}

var myClass = new MyClass("ASD", "QWE");
alert(myClass.Field1); // voila! statement completion on these properties

6
আমার গভীর ক্ষমা। তবে আপনি আসলে "ফিল্ড ইনিশিয়ালাইজারদের সম্পর্কে জিজ্ঞাসা করেন নি", তাই এটি টিএসে ক্লাস নতুন করার বিকল্প পদ্ধতিতে আপনার আগ্রহী হতে পারে তা ধরে নেওয়া স্বাভাবিক। আপনি যদি ডাউনটাতে প্রস্তুত হন তবে আপনি আপনার প্রশ্নে একটি সামান্য বিট তথ্য দিতে পারেন।
— রাল্ফ ল্যাভেললে

+1 কনস্ট্রাক্টর হ'ল সম্ভব যেখানে যাওয়ার উপায়; তবে এমন ক্ষেত্রে যেখানে আপনার অনেক ক্ষেত্র রয়েছে এবং কেবলমাত্র সেগুলির কয়েকটি সূচনা করতে চান, আমি মনে করি আমার উত্তর জিনিসগুলিকে আরও সহজ করে।
— মেইরিওন হিউজেস

1
আপনার যদি অনেক ক্ষেত্র থাকে তবে এই জাতীয় কোনও বস্তুর প্রারম্ভিককরণটি বেশ অযৌক্তিক হবে কারণ আপনি নির্মাতাকে নামহীন মানগুলির প্রাচীর দিয়ে যাচ্ছেন। এই পদ্ধতির কোনও যোগ্যতা নেই তা বলার অপেক্ষা রাখে না; এটি কয়েকটি ক্ষেত্র সহ সহজ জিনিসগুলির জন্য সবচেয়ে ভাল ব্যবহৃত হবে। বেশিরভাগ প্রকাশনা বলে যে কোনও সদস্যের স্বাক্ষরের চার বা পাঁচটি পরামিতি হ'ল উপরের সীমা। কেবল এটি দেখিয়েছি কারণ টিএস প্রারম্ভিকদের অনুসন্ধানের সময় আমি কারও ব্লগে এই সমাধানের একটি লিঙ্ক পেয়েছি। আমার কাছে 20+ ক্ষেত্র সহ অবজেক্ট রয়েছে যা ইউনিট পরীক্ষার জন্য আরম্ভ করা দরকার।
— ডাস্টিন ক্লেভল্যান্ড

11

কিছু পরিস্থিতিতে এটি ব্যবহারের জন্য গ্রহণযোগ্য হতে পারে Object.create। মোজিলা রেফারেন্সটিতে একটি পলিফিল অন্তর্ভুক্ত রয়েছে যদি আপনার ব্যাক-সামঞ্জস্যতা প্রয়োজন হয় বা আপনার নিজের ইনিশিয়ালাইজার ফাংশনটি রোল করতে চান।

আপনার উদাহরণ প্রয়োগ করা:

Object.create(Person.prototype, {
    'Field1': { value: 'ASD' },
    'Field2': { value: 'QWE' }
});

দরকারী দৃশ্যপট

  • ইউনিট টেস্ট
  • ইনলাইন ঘোষণা ration

আমার ক্ষেত্রে আমি দুটি কারণে ইউনিট পরীক্ষায় এই দরকারীটি পেয়েছি:

  1. প্রত্যাশা পরীক্ষা করার সময় আমি প্রায়শই প্রত্যাশা হিসাবে একটি পাতলা বস্তু তৈরি করতে চাই
  2. ইউনিট পরীক্ষার ফ্রেমওয়ার্কগুলি (জেসমিনের মতো) অবজেক্ট প্রোটোটাইপ ( __proto__) এর তুলনা করতে পারে এবং পরীক্ষায় ব্যর্থ হতে পারে। উদাহরণ স্বরূপ:
var actual = new MyClass();
actual.field1 = "ASD";
expect({ field1: "ASD" }).toEqual(actual); // fails

ইউনিট পরীক্ষার ব্যর্থতার আউটপুট কী মিলছে না সে সম্পর্কে কোনও ধারণা দেবে না।

  1. ইউনিট পরীক্ষায় আমি কোন ব্রাউজারগুলি সমর্থন করি সে সম্পর্কে আমি নির্বাচনী হতে পারি

শেষ অবধি, http://tyypecript.codeplex.com/workitem/334 এ প্রস্তাবিত সমাধান ইনলাইন জেসন-স্টাইল ঘোষণাকে সমর্থন করে না। উদাহরণস্বরূপ, নিম্নলিখিতগুলি সংকলন করে না:

var o = { 
  m: MyClass: { Field1:"ASD" }
};

9

আমি এমন একটি সমাধান চেয়েছিলাম যার সাথে নিম্নলিখিতটি থাকবে:

  • সমস্ত ডেটা অবজেক্টগুলি প্রয়োজনীয় এবং এটি অবশ্যই কনস্ট্রাক্টরের দ্বারা পূরণ করতে হবে।
  • ডিফল্ট সরবরাহ করার প্রয়োজন নেই।
  • ক্লাসের ভিতরে ফাংশন ব্যবহার করতে পারে।

আমি এখানে এটি করার উপায়:

export class Person {
  id!: number;
  firstName!: string;
  lastName!: string;

  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }

  constructor(data: OnlyData<Person>) {
    Object.assign(this, data);
  }
}

const person = new Person({ id: 5, firstName: "John", lastName: "Doe" });
person.getFullName();

কনস্ট্রাক্টরের সমস্ত সম্পত্তি বাধ্যতামূলক এবং সংকলক ত্রুটি ছাড়া বাদ দেওয়া যাবে না।

এটি নির্ভর করে OnlyDataযে getFullName()প্রয়োজনীয় বৈশিষ্ট্যগুলি থেকে ফিল্টার আউট করে এবং এটি এর মতো সংজ্ঞায়িত হয়:

// based on : https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c
type FilterFlags<Base, Condition> = { [Key in keyof Base]: Base[Key] extends Condition ? never : Key };
type AllowedNames<Base, Condition> = FilterFlags<Base, Condition>[keyof Base];
type SubType<Base, Condition> = Pick<Base, AllowedNames<Base, Condition>>;
type OnlyData<T> = SubType<T, (_: any) => any>;

এইভাবে বর্তমান সীমাবদ্ধতা:

  • টাইপস্ক্রিপ্ট 2.8 প্রয়োজন
  • গেটার / সেটার সহ ক্লাস

এই উত্তরটি আমার কাছে সবচেয়ে কাছের বলে মনে হচ্ছে। আমরা যদি
— টাইপস্ক্রিপ্ট

1
আমি যতদূর বলতে পারি এটি আজকের মতো এগিয়ে যাওয়ার সেরা উপায়। ধন্যবাদ.
— ফ্লোরিয়ান নরবার্ট বেপঙ্ক্ট

এই সমাধানটির সাথে একটি সমস্যা রয়েছে, @ ভিটালিবি: পদ্ধতিগুলির পরামিতিগুলি হওয়ার সাথে সাথেই এই ব্রেক হয়ে যায়: getFullName () {রিটার্ন "বার"} কাজ করে, getFullName (str: স্ট্রিং): স্ট্রিং {রিটার্ন স্ট্র} কাজ করে না
— ফ্লোরিয়ান নরবার্ট

আপনার জন্য ঠিক কী কাজ করছে না? মনে হচ্ছে এটি আমার পক্ষে ভাল কাজ করছে ...
— rfgamaral

3

এটি অন্য একটি সমাধান:

return {
  Field1 : "ASD",
  Field2 : "QWE" 
} as myClass;

2

Youচ্ছিক ক্ষেত্রগুলির সাথে (আপনার সাথে চিহ্নিত?) এবং একই বর্গের উদাহরণ গ্রহণকারী একটি নির্মাতা সহ একটি ক্লাস থাকতে পারে।

class Person {
    name: string;     // required
    address?: string; // optional
    age?: number;     // optional

    constructor(person: Person) {
        Object.assign(this, person);
    }
}

let persons = [
    new Person({ name: "John" }),
    new Person({ address: "Earth" }),    
    new Person({ age: 20, address: "Earth", name: "John" }),
];

এই ক্ষেত্রে, আপনি প্রয়োজনীয় ক্ষেত্রগুলি বাদ দিতে পারবেন না। এটি আপনাকে অবজেক্ট নির্মাণের উপর সূক্ষ্ম-নিয়ন্ত্রণযুক্ত নিয়ন্ত্রণ দেয়।

অন্যান্য জবাব হিসাবে উল্লিখিত হিসাবে আপনি আংশিক প্রকারের সাথে নির্মাণকারী ব্যবহার করতে পারেন:

public constructor(init?:Partial<Person>) {
    Object.assign(this, init);
}

সমস্যাটি হ'ল সমস্ত ক্ষেত্রগুলি alচ্ছিক হয়ে যায় এবং বেশিরভাগ ক্ষেত্রে এটি কাম্য নয়।


1

এটি করার সহজতম উপায় হ'ল টাইপ কাস্টিং।

return <MyClass>{ Field1: "ASD", Field2: "QWE" };

7
দুর্ভাগ্যক্রমে, (1) এটি টাইপ-কাস্টিং নয়, তবে একটি সংকলন-টাইপ টাইপ- দাবি , (২) প্রশ্নটি "কীভাবে নতুন ক্লাস শুরু করা যায় " (জোর খনি) জিজ্ঞাসা করেছিল, এবং এই পদ্ধতিটি এটি সম্পাদন করতে ব্যর্থ হবে। টাইপস্ক্রিপ্টের এই বৈশিষ্ট্যটি থাকলে এটি অবশ্যই দুর্দান্ত হবে, তবে দুর্ভাগ্যক্রমে, ঘটনাটি এটি নয়।
— জন ওয়েইজ

সংজ্ঞা কোথায় MyClass?
— Jeb50

0

আপনি যদি টাইপ স্ক্রিপ্ট <2.1 এর একটি পুরানো সংস্করণ ব্যবহার করছেন তবে আপনি নিম্নলিখিতগুলির মতো একইরকম ব্যবহার করতে পারেন যা মূলত টাইপড অবজেক্টে যেকোনটির কাস্টিং রয়েছে:

const typedProduct = <Product>{
                    code: <string>product.sku
                };

দ্রষ্টব্য: এই পদ্ধতিটি ব্যবহার করা কেবলমাত্র ডেটা মডেলগুলির পক্ষে ভাল কারণ এটি বস্তুর সমস্ত পদ্ধতি মুছে ফেলবে। এটি মূলত কোনও টাইপ করা অবজেক্টে কোনও বস্তু castালাই করছে


-1

উদাহরণস্বরূপ আপনি যদি প্রাথমিক মান সেট না করেই নতুন উদাহরণ তৈরি করতে চান

1- আপনাকে ক্লাস নট ইন্টারফেস ব্যবহার করতে হবে

2- ক্লাস তৈরি করার সময় আপনাকে প্রাথমিক মান নির্ধারণ করতে হবে

export class IStudentDTO {
 Id:        number = 0;
 Name:      string = '';


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