मैं टाइपस्क्रिप्ट में इंटरफ़ेस फ़ाइल परिभाषा के आधार पर एक ऑब्जेक्ट कैसे बना सकता हूं?


313

मैंने एक इंटरफ़ेस इस तरह परिभाषित किया है:

interface IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
 }

मैं इस तरह एक चर को परिभाषित करता हूं:

var modal: IModal;

हालांकि, जब मैं मोडल की संपत्ति को सेट करने की कोशिश करता हूं तो यह मुझे एक संदेश देता है

"cannot set property content of undefined"

क्या मेरी मोडल ऑब्जेक्ट का वर्णन करने के लिए इंटरफ़ेस का उपयोग करना ठीक है और यदि ऐसा है तो मुझे इसे कैसे बनाना चाहिए?

जवाबों:


426

यदि आप कहीं और "मोडल" वैरिएबल बना रहे हैं, और टाइपस्क्रिप्ट बताना चाहते हैं तो यह सब हो जाएगा, आप उपयोग करेंगे:

declare const modal: IModal;

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

const modal: IModal = {
    content: '',
    form: '',
    href: '',
    $form: null,
    $message: null,
    $modal: null,
    $submits: null
};

या झूठ, एक प्रकार के दावे के साथ, लेकिन आप प्रकार की सुरक्षा खो देंगे क्योंकि अब आप अनपेक्षित स्थानों में अपरिभाषित हो जाएंगे, और संभवतः रनटाइम त्रुटियां, जब पहुंच modal.contentऔर इतने पर (गुण जो अनुबंध कहता है कि वहां होगा)।

const modal = {} as IModal;

उदाहरण वर्ग

class Modal implements IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
}

const modal = new Modal();

आप सोच सकते हैं "अरे यह वास्तव में इंटरफ़ेस का दोहराव है" - और आप सही हैं। यदि मोडल वर्ग IModal इंटरफ़ेस का एकमात्र कार्यान्वयन है जिसे आप इंटरफ़ेस को पूरी तरह से हटाना चाहते हैं और उपयोग कर सकते हैं ...

const modal: Modal = new Modal();

बजाय

const modal: IModal = new Modal();

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

1
हां - आप एक वर्ग को परिभाषित कर सकते हैं और तब आपको केवल नए उदाहरण बनाने होंगे जब आपको उनकी आवश्यकता होगी। क्या आपको एक उदाहरण की आवश्यकता है?
फेंटन

2
मैंने इंटरफ़ेस के बारे में एक उदाहरण और एक नोट जोड़ा है।
फेंटन

21
var modal = <IModal>{};यह वही है जो मैं देख रहा था ;-) धन्यवाद!
लेजेंड्स

5
FYI करें, इसके {} as IModalबजाय इसका उपयोग करना बेहतर है <IModal>{}। यह <foo>JSX में शैली अभिकथन का उपयोग करते समय भाषा व्याकरण में एक अस्पष्टता को हटा देता है । और अधिक पढ़ें । और निश्चित रूप से, के बजाय का उपयोग करें letया । constvar
एलेक्स क्लॉस

191

यदि आप एक इंटरफ़ेस की खाली वस्तु चाहते हैं, तो आप बस कर सकते हैं:

var modal = <IModal>{};

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

class TestClass {
    a: number;
    b: string;
    c: boolean;
}

में संकलित करता है

var TestClass = (function () {
    function TestClass() {
    }
    return TestClass;
})();

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


1
`उपरोक्त टिप्पणी पर जोड़ने के लिए। एक फ़ंक्शन "अपडेटमॉडल (IModal modalInstance) {}" को कॉल करने के लिए, आप इंटरफ़ेस 'IModal' का इनलाइन उदाहरण बना सकते हैं, जैसे: // कुछ कोड यहां, जहां updateModal फ़ंक्शन और IMDal सुलभ हैं: updateModal (<IModal> {// यह पंक्ति एक उदाहरण सामग्री बनाती है: '', फ़ॉर्म: '', href: '', $ फॉर्म: अशक्त, $ संदेश: अशक्त, $ मोडल: अशक्त, $ विनम्र: अशक्त}); // अपना कोड पूरा करें `
सनी

का उपयोग करके var modal= <abc>{}हम सिर्फ खाली वस्तु के प्रकार एबीसी के modal सौंपा है, लेकिन जहां हम modal के प्रकार की घोषणा की है? मैं टाइपस्क्रिप्ट 6 का उपयोग कर रहा हूं।
परदीप जैन

यह मेरे लिए काम नहीं करता था मुझे स्वीकार किए गए उत्तर में बताए गए पूरे ऑब्जेक्ट को इनिशियलाइज़ करना था।
राहुल सोनवंशी

52

यदि आप रिएक्ट का उपयोग कर रहे हैं, तो पार्सर पारंपरिक कास्ट सिंटैक्स पर चोक कर देगा। इसलिए .tsx फ़ाइलों का उपयोग करने के लिए एक विकल्प पेश किया गया था।

let a = {} as MyInterface;

https://www.typescriptlang.org/docs/handbook/jsx.html


22

मुझे लगता है कि आपके पास ऐसा करने के लिए मूल रूप से पांच अलग-अलग विकल्प हैं। आप जो लक्ष्य हासिल करना चाहते हैं उसके आधार पर उनमें से चुनना आसान हो सकता है।

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

interface IModal {
    content: string;
    form: string;
    //...

    //Extra
    foo: (bar: string): void;
}

class Modal implements IModal {
    content: string;
    form: string;

    foo(param: string): void {
    }
}

यहां तक ​​कि अगर अन्य तरीके एक इंटरफ़ेस से एक ऑब्जेक्ट बनाने के लिए आसान तरीके पेश कर रहे हैं, तो आपको अपने इंटरफ़ेस को अलग करने पर विचार करना चाहिए , यदि आप अलग-अलग मामलों के लिए अपनी ऑब्जेक्ट का उपयोग कर रहे हैं, और यह इंटरफ़ेस को अलग नहीं करता है:

interface IBehaviour {
    //Extra
    foo(param: string): void;
}

interface IModal extends IBehaviour{
    content: string;
    form: string;
    //...
}

दूसरी ओर, उदाहरण के लिए, इकाई के परीक्षण के दौरान आपका कोड (यदि आप बार-बार चिंताओं के पृथक्करण को लागू नहीं कर सकते हैं), तो आप उत्पादकता की खातिर कमियां स्वीकार करने में सक्षम हो सकते हैं। आप ज्यादातर अन्य तृतीय पक्ष * .d.ts इंटरफेस के लिए नकली बनाने के लिए अन्य तरीके लागू कर सकते हैं। और यह हर विशाल इंटरफ़ेस के लिए हमेशा पूर्ण अनाम वस्तुओं को लागू करने के लिए एक दर्द हो सकता है।

इस रास्ते पर आपका पहला विकल्प एक खाली वस्तु बनाना है :

 var modal = <IModal>{};

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

var modal: IModal = {
    content: '',
    form: '',
    //...

    foo: (param: string): void => {
    }
};

तीसरा आप अपने इंटरफेस का सिर्फ एक हिस्सा बना सकते हैं और एक अनाम ऑब्जेक्ट बना सकते हैं, लेकिन इस तरह से आप अनुबंध को पूरा करने के लिए जिम्मेदार हैं

var modal: IModal = <any>{
    foo: (param: string): void => {

    }
};

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



12

चूंकि मुझे शीर्ष में एक समान उत्तर नहीं मिला है और मेरा उत्तर अलग है। मैं करता हूँ:

modal: IModal = <IModal>{}

2

अपने इंटरफ़ेस का उपयोग करके आप कर सकते हैं

class Modal() {
  constructor(public iModal: IModal) {
   //You now have access to all your interface variables using this.iModal object,
   //you don't need to define the properties at all, constructor does it for you.
  }
}

2

यहाँ एक और दृष्टिकोण है:

आप बस इस तरह एक ESLint अनुकूल वस्तु बना सकते हैं

const modal: IModal = {} as IModal;

या इंटरफ़ेस पर और डिफ़ॉल्ट चूक के साथ एक डिफ़ॉल्ट उदाहरण, यदि कोई हो

const defaultModal: IModal = {
    content: "",
    form: "",
    href: "",
    $form: {} as JQuery,
    $message: {} as JQuery,
    $modal: {} as JQuery,
    $submits: {} as JQuery
};

फिर डिफ़ॉल्ट उदाहरण की विविधता बस कुछ गुणों को ओवरराइड करके

const confirmationModal: IModal = {
    ...defaultModal,     // all properties/values from defaultModal
    form: "confirmForm"  // override form only
}

1

अब तक पोस्ट किए गए समाधानों में से कई उपयोग प्रकार के दावे और उसके बाद संकलन त्रुटियों को फेंक नहीं देते हैं यदि आवश्यक इंटरफ़ेस गुण कार्यान्वयन में छोड़ दिए जाते हैं।

कुछ अन्य मजबूत, कॉम्पैक्ट समाधानों में रुचि रखने वालों के लिए :

विकल्प 1: इंटरफ़ेस को लागू करने वाले अनाम वर्ग को त्वरित करें:

new class implements MyInterface {
  nameFirst = 'John';
  nameFamily = 'Smith';
}();

विकल्प 2: एक उपयोगिता फ़ंक्शन बनाएँ:

export function impl<I>(i: I) { return i; }

impl<MyInterface>({
  nameFirst: 'John';
  nameFamily: 'Smith';
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.