2012-10-18 13 views
9

मैं टाइपप्रति में निर्माण हस्ताक्षरों के साथ इंटरफेस के साथ एक सा खेलने किया गया है टाइप नहीं है, और जब जांच टाइप करने में विफल निम्न मैं थोड़ा उलझन में बने:इंटरफेस जाँच

class Foo { 
    constructor() { 
    } 
} 

interface Bar { 
    new(): Bar; 
} 

function Baz(C : Bar) { 
    return new C() 
} 

var o = Baz(Foo); 

प्रकार की त्रुटि है :

आपूर्ति मापदंडों कॉल लक्ष्य के किसी भी हस्ताक्षर मेल नहीं खाते: प्रकार 'बार' एक निर्माण हस्ताक्षर की आवश्यकता है, लेकिन प्रकार: प्रकार 'नई() => फू' और 'बार' हैं असंगत के हस्ताक्षर का निर्माण 'फू' की कमी एस एक (सी: बार) => बार

फू के निर्माता का प्रकार() => फू है, और यही वह है जो मैंने सोचा था कि बार ने कहा था। क्या मुझसे कोई चूक हो रही है?

उत्तर

1

समस्या (कम से कम टाइपस्क्रिप्ट कंपाइलर के दृष्टिकोण से) Bar की new विधि का हस्ताक्षर है। आप निम्नलिखित के साथ Bar की परिभाषा,

interface Bar { 
    new(): any; 
} 

यह काम करता है की जगह है। आप new(): Foo का उपयोग भी कर सकते हैं, केवल Bar क्योंकि वापसी मान काम नहीं करता है।

5

यहां सूक्ष्म परिवर्तन के साथ आपके कोड का एक अद्यतन संस्करण है।

हम Bar इंटरफ़ेस को परिभाषित करते हैं जो कि हम जो भी कार्य और चर मौजूद हैं, उसके साथ हम परिभाषित करते हैं।

अगला, हम Bar इंटरफ़ेस NewableBar इंटरफ़ेस के साथ इंटरफ़ेस बढ़ाते हैं। यह सिर्फ एक निर्माता को परिभाषित करता है जो Bar देता है।

क्योंकि FooBar लागू करता है और एक निर्माता है और Baz एक NewableBar की आवश्यकता है, सब कुछ चेक किया गया है।

यह any से थोड़ा अधिक वर्बोज़ है - लेकिन आपको वह चेकिंग देता है जो आप चाहते हैं।

interface Bar { 

} 

interface NewableBar extends Bar { 
    new(); 
} 

class Foo implements Bar { 
    constructor() { 

    } 
} 

function Baz(C : NewableBar) { 
    return new C() 
} 

var o = Baz(Foo); 
+0

'किसी भी' का उपयोग करने के बजाय आप एक सुपर इंटरफेस का उपयोग करते हैं (आप 'उपकरण' और 'विस्तार', बीटीडब्ल्यू छोड़ सकते हैं)। यह ठीक है, मुझे लगता है, और 'किसी भी' से बेहतर है, लेकिन एक चीज अभी भी मुझे खराब करती है: आप 'न्यूबलबैर :: नया() '' न्यूबलबैर' वापस क्यों नहीं दे सकते? यह एक प्रकार क्यों होना चाहिए जो 'न्यूबलबार 'से अधिक सामान्य ** है (और स्पष्ट रूप से कम से कम' फू 'के रूप में सामान्य)? –

+0

@AdrianLang मैंने स्पष्ट विरासत और कार्यान्वयन को स्पष्ट होने के लिए रखा है, लेकिन आप सही हैं - टाइपस्क्रिप्ट खुशी से उनसे अनुमान लगाएगा यदि सबकुछ मेल खाता है। किसी विशेष प्रकार के रूप में विधि पर 'नया()' हस्ताक्षर का इलाज करने का प्रयास करते समय एक व्याख्या समस्या होती है। – Fenton

+0

लेकिन, जब भी आप Foo में कुछ भी जोड़ने का प्रयास करते हैं तो यह टूट जाता है। संपादित करें: क्षमा करें, मैं इसे गलत कर रहा था। मेरा निर्माण हस्ताक्षर होना चाहिए: 'नया (... _: कोई []): बार; ' – farre

1

मुझे लगता है कि मुझे पता है कि आप यह कहां ले रहे हैं और मुझे लगता है कि आपको एक अलग दृष्टिकोण की आवश्यकता है।

यह उदाहरण निम्नलिखित कहते हैं:

  • बाज चाहिए एक आइटम कि newable है पारित किया जा
  • बाज एक बार
  • newable होने के लिए नहीं सभी बार की जरूरत को वापस आ जाएगी, केवल उन बाज

यहाँ करने के लिए पारित किया जा रहा उदाहरण है:

interface Bar { 
    sayHello(name: string): void; 
} 

interface Newable { 
    new(); 
} 

class Foo implements Bar { 
    constructor() { 

    } 

    sayHello(name: string) { 
     window.alert('Hello ' + name); 
    } 
} 

function Baz(C : Newable) { 
    return <Bar> new C() 
} 

var o = Baz(Foo); 
o.sayHello('Bob'); 

इस का केवल खतरे दृष्टिकोण यह है कि आप कुछ नया पास कर सकते हैं जो बाज़ फ़ंक्शन के लिए बार नहीं था।चूंकि आप किसी तर्क से ऑब्जेक्ट बनाकर गतिशील सुविधा का उपयोग कर रहे हैं, यह काफी हद तक अपरिहार्य है जब तक कि आप पूर्व-प्रारंभिक ऑब्जेक्ट में पास करने के इच्छुक नहीं होते हैं, इस स्थिति में बाज़ काफी हद तक एक नए के बजाय बार को स्वीकार करेंगे।

+0

हां, इन पंक्तियों के साथ कुछ मैं प्राप्त करना चाहता था। अपवाद के साथ कि मैं एक बार इंटरफेस होने के लिए 'बार' और 'न्यूबल' करना चाहता था। धन्यवाद। – farre

1

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मुझे आज के समान कुछ की आवश्यकता थी और पोस्ट में आया।

interface Bar { 
    sayHello(name: string); 
} 

class Foo implements Bar { 
    sayHello(name: string) { 
     window.alert("Hello " + name); 
    } 
} 

function Baz(c: new() => Bar) { 
    return new C(); 
} 

var o = Baz(Foo); 
o.sayHello("Bob"); 

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

function Baz<T extends Bar>(c: new() => T) { 
    return new c(); 
} 

var o = Baz(Foo); 

'ओ' के रूप में प्रकार फू अनुमान लगाया जा होगा।

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