2014-04-11 6 views
7

यह कुछ है जो मैं टाइपस्क्रिप्ट के पुराने संस्करणों में कर रहा हूं और मैं इस विधि का उपयोग सी # में करता हूं, लेकिन यह टाइपस्क्रिप्ट के नवीनतम 1.0 संस्करण में काम नहीं करता है।टाइप 0 की बाधा के लिए समर्थन के नुकसान के आसपास काम करना

यहाँ क्या अतीत में काम किया है:

class Base<T extends Base<T>> { 
    public children : Array<T>; 

    doAction() { 
     this.children[0].promise(); // used to work 
    } 

    promise() : T { 
     return this; // used to work 
    } 
} 

class Child extends Base<Child> { 
    public myString: string; 
} 

new Child().promise().myString; // used to work 

सब कुछ सद्भाव में काम करता था।

अब टाइपप्रति 1.0 में मैं Base<T extends Base<T>> परिभाषा पर इस त्रुटि मिलती है:

एक प्रकार पैरामीटर की बाधा एक ही प्रकार के पैरामीटर सूची से किसी भी प्रकार पैरामीटर संदर्भ नहीं दे सकता।

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

+0

ध्यान दें कि इस पद्धति को अब जरूरी होगा जब टाइपप्रति एक [बहुरूपी इस] (https का समर्थन करता है। कॉम/माइक्रोसॉफ्ट/टाइपस्क्रिप्ट/पुल/4 9 10) टीएस 1.7 में। –

उत्तर

10

अब आप यहाँ T उपयोग करने के लिए अनुमति दी जाती है:

class Base<T extends Base<T>> 
--------------------------^ 

आप या तो अपने वर्ग गैर सामान्य या उपयोग करने के लिए है:

class Base<T extends Base<any>> 

कारण इस के लिए दिया करने के लिए किया गया था सरल संकलक:

भाषा को सरल बनाने के लिए हमारे निरंतर प्रयास में, हम सरल बना रहे हैं क्या सामान्य सी onstraints लागू कर सकते हैं।

टाइप-चेकिंग, त्रुटि-रिपोर्टिंग और डिज़ाइन जटिलता के मामले में अतिरिक्त ओवरहेड ने 1.0 के लिए इसे सार्थक बनाने के लिए पर्याप्त अतिरिक्त अभिव्यक्ति नहीं जोड़ा। हम टाइपस्क्रिप्ट के भविष्य के संस्करणों में इसे फिर से देख सकते हैं।

- Breaking Changes Wiki

+0

धन्यवाद। यह उतना अच्छा नहीं है, लेकिन मैं 'बेस <टी बेस >' बढ़ाकर चीजों को काम करने में सक्षम था। मुझे किसी के लिए एक कलाकार करना था, लेकिन यह बेस क्लास के भीतर एक बड़ा सौदा नहीं है: http://goo.gl/8JSLxq –

6

मैं क्योंकि वह Base<T extends Base<any>> उपयोग करने के लिए सुझाव दिया स्टीव जवाब स्वीकार किए जाते हैं, लेकिन मैं कोड में परिवर्तन करना है कि स्टैक ओवरफ़्लो पर समस्या का समाधान होने की एक प्रति रखना चाहते थे:

class Base<T extends Base<any>> { // 1. Set as any 
    children: Array<T>; 

    doAction() { 
     this.children[0].promise(); 
    } 

    promise(): T { 
     return <any> this; // 2. cast to any 
    } 
} 

class Child extends Base<Child> { 
    public myString: string; 
} 

new Child().promise().myString; 

इसके लिए किसी भी कलाकार की आवश्यकता होती है, लेकिन यह बहुत खराब नहीं है क्योंकि यह केवल बेस क्लास में है। यह परिवर्तन बाल या बेस वर्गों का उपयोग करके कुछ भी प्रभावित नहीं करता है, इसलिए कुल मिलाकर यह एक आदर्श विकल्प था।


अद्यतन: टीएस में 1.7+ इस का उपयोग किया जा सकता है एक polymorphic this:

class Base { 
    children: Array<this>; 

    doAction() { 
     this.children[0].promise(); 
    } 

    promise(): this { 
     return this; 
    } 
} 

class Child extends Base { 
    public myString: string; 
} 

new Child().promise().myString; 
+0

अद्भुत दोस्त, धन्यवाद –

0

promise() : T { return this; } यह, बहुत कमजोर धारणा को आसानी से तोड़ा जा सकता है कि कारण यह है एक आधार वर्ग में परिभाषित downcasting बस किसी भी उप-वर्ग

उदाहरण के लिए, यदि कोई class SuperChild extends Child {} परिभाषित करता है तो SuperChild आपकोदेने जा रहा है SuperChild के बजाय।

कि यहां इसके अलावा आप कैसे इसे जिस तरह से यह काम करने के लिए इस्तेमाल कर सकते हैं: // GitHub:

class Base<T> { 
    public children : Array<T>; 

    constructor(
     private toSelf:() => T, 
     private toBase: (something: T) => Base<T> 
    ) { 
    } 


    doAction() { 
     this.toBase(this.children[0]).promise(); // used to work 
    } 

    promise() : T { 
     return this.toSelf(); // 
    } 
} 

class Child extends Base<Child> { 
    public myString: string; 
} 

function toThis() { return this; } 

new Child(toThis, x => x).promise().myString; // used to work 
संबंधित मुद्दे