2013-01-15 20 views
70

टाइपस्क्रिप्ट में "घोषणा श्रेणी" और "इंटरफ़ेस" के बीच क्या अंतर है, .d.ts स्रोत घोषणा फ़ाइलों को बनाते समय, जो बेहतर है और क्यों?टाइपस्क्रिप्ट

declare class Example { 
    public Method(): void; 
} 

या

interface Example { 
    Method(): void; 
} 

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

+0

देखें http://stackoverflow.com/a/14323673/1704166 –

+0

मुझे नहीं लगता कि इनमें से कोई भी वास्तव में वर्णन करने में मदद करता है कि आप एक दूसरे का उपयोग करेंगे क्योंकि वे दोनों एक ही जेएस आउटपुट के साथ एक ही चीज़ को पूरा कर सकते हैं। – Chris

उत्तर

118

interface तब होता है जब आप किसी ऑब्जेक्ट के आकार का वर्णन करना चाहते हैं। इंटरफेस के लिए, कभी भी कोड जनरेशन नहीं है - वे पूरी तरह से टाइप सिस्टम में एक आर्टिफैक्ट हैं। आपको implements क्लॉज के आधार पर कक्षा के लिए कोड जनरेशन में कोई अंतर नहीं दिखाई देगा।

declare class जब आप एक मौजूदा वर्ग का वर्णन करना चाहते के लिए है (आमतौर पर एक टाइपप्रति वर्ग, लेकिन हमेशा नहीं) है कि बाहर से उपस्थित होने जा रहा है (उदाहरण के लिए, आप दो .ts फ़ाइलों को दो .js को संकलित किया है फ़ाइलों और दोनों को वेबपृष्ठ में script टैग के माध्यम से शामिल किया गया है)। यदि आप class से extends का उपयोग करते हैं (भले ही बेस प्रकार declare class या नियमित class) है, तो संकलक प्रोटोटाइप श्रृंखला को हुक करने और रचनाकारों को अग्रेषित करने के लिए सभी कोड उत्पन्न करने जा रहा है और क्या नहीं।

यदि आप declare class से प्राप्त करने का प्रयास करते हैं जो एक इंटरफ़ेस होना चाहिए, तो आपके पास रनटाइम त्रुटि होगी क्योंकि वह जेनरेट कोड किसी ऑब्जेक्ट का संदर्भ नहीं देगा जिसमें कोई रनटाइम अभिव्यक्ति नहीं है।

इसके विपरीत, यदि आप implement एक इंटरफ़ेस जो declare class होना चाहिए, तो आपको अपने सभी सदस्यों को फिर से कार्यान्वित करना होगा और इच्छानुसार किसी भी कोड पुन: उपयोग का लाभ नहीं उठाएगा। बेस क्लास बनें, और रनटाइम पर प्रोटोटाइप चेन की जांच करने वाले फ़ंक्शंस आपके ऑब्जेक्ट को अस्वीकार कर देंगे क्योंकि वास्तव में बेस क्लास का उदाहरण नहीं है।

वास्तव में nerdy प्राप्त करने के लिए, यदि आप एक सी ++ पृष्ठभूमि है, आप मोटे तौर पर एक निर्माता है कि सख्ती से इस संकलन इकाई में एक परिभाषा का अभाव का एक extern घोषणा के रूप में interface रूप typedef और declare class के बारे में सोच सकते हैं।

एक शुद्ध खपत की ओर से (अनिवार्य कोड लिखने, नए प्रकार जोड़ने नहीं), interface और declare class के बीच फर्क सिर्फ इतना है कि आप नहीं कर सकते हैं new एक इंटरफेस। हालांकि, यदि आप extend/implement का एक नया class में इन प्रकारों में से एक का इरादा रखते हैं, तो आपको बिल्कुल interface और declare class के बीच सही ढंग से चुना होगा। उनमें से केवल एक काम करेगा।

दो नियम है कि आप अच्छी तरह से काम करेगा:

  • एक निर्माता समारोह (new के साथ कुछ invokable) के साथ प्रकार से संरेखित करने का नाम है कि वास्तव में कार्यावधि में मौजूद है (उदाहरण के लिए Date है, लेकिन JQueryStatic नहीं है) ? यदि कोई है, तो आप निश्चित रूप से interface
  • क्या मैं किसी अन्य टाइपस्क्रिप्ट फ़ाइल से संकलित कक्षा से निपट रहा हूं, या कुछ समान समान है? यदि हाँ, का उपयोग declare class
+0

आप वास्तव में टाइपस्क्रिप्ट में एक इंटरफ़ेस नया कर सकते हैं। एकमात्र सीमा विरासत है। –

+2

आप 'नए' ऑपरेटर को इंटरफ़ेस प्रकार पर नहीं बुला सकते हैं। हालांकि, इंटरफेस में निर्माण हस्ताक्षर हो सकते हैं, जिसका अर्थ है कि आप 'नए' ऑपरेटर को इंटरफ़ेस प्रकार के मान पर आक्रमण कर सकते हैं। यह 'वर्ग' कैसे काम करता है उससे अलग है, जहां उस प्रकार की अभिव्यक्ति के बजाय निर्माण हस्ताक्षर स्वयं नाम के नाम पर है। –

+0

यदि आप किसी इंटरफ़ेस में कन्स्ट्रक्टर जोड़ने का मार्ग जाते हैं, तो कक्षा के 'statics' को छोड़कर, यह इंटरफ़ेस का केवल सदस्य होना चाहिए। निर्मित ऑब्जेक्ट के इंटरफ़ेस के साथ कन्स्ट्रक्टर फ़ंक्शन के इंटरफ़ेस को गठबंधन न करें। यदि आप करते हैं, तो टाइप सिस्टम सिल्लनेस की तरह अनुमति देता है: नया (नया एक्स()), जहां एक्स: इंटरफेस। –

12

आप इंटरफ़ेस को लागू कर सकते हैं:

class MyClass implements Example { 
    Method() { 

    } 
} 

जबकि declare class वाक्य रचना वास्तव में बाहरी कोड कि टाइपप्रति में नहीं लिखा है के लिए प्रकार परिभाषाएं जोड़ने के लिए इस्तेमाल किया जा करने का इरादा है - तो कार्यान्वयन है "कहीं और"।

+0

तो आप सुझाव दे रहे हैं कि टाइपस्क्रिप्ट में लिखे गए कोड का वर्णन करने के लिए घोषित कक्षा का उपयोग नहीं किया जाना चाहिए? मुझे लगता है कि मामला, लेकिन jquery.d.ts फ़ाइल में चेक किया गया है, JQueryStatic एक इंटरफ़ेस है जो लागू किया गया है: var $ घोषित करें: JQueryStatic हालांकि यह होने के बावजूद कक्षा $ { सार्वजनिक स्थैतिक घोषित करेगा .. } – Chris

+0

एकमात्र कारण मैं इसके बारे में सोच सकता हूं यदि आप नहीं चाहते थे कि लोग वर्ग का विस्तार करें - इंटरफ़ेस का उपयोग करके इसका मतलब है कि आपको संपूर्ण कार्यान्वयन की आवश्यकता होगी। – Fenton

+0

समझ में आता है। शायद यही कारण था। – Chris

3

आम आदमी की दृष्टि में, declare.ts/d.ts फाइलों में प्रयोग किया जाता है संकलक है कि हम कीवर्ड हम declaring कि वातावरण में मौजूद हैं की उम्मीद करनी चाहिए बताने के लिए, भले ही यह नहीं है वर्तमान फ़ाइल में परिभाषित किया गया। इसके बाद घोषित ऑब्जेक्ट का उपयोग करते समय हमें टाइप सुरक्षा की अनुमति मिल जाएगी, क्योंकि टाइपस्क्रिप्ट कंपाइलर अब जानता है कि कुछ अन्य घटक उस चर को प्रदान कर सकते हैं।

संबंधित मुद्दे