देखें microsoft/टाइपप्रति#41164 के लिए एक विहित इस सवाल का जवाब.
टाइपप्रति करता है की अनुमति परिपत्र संदर्भ में सामान्य इंटरफेस और सामान्य कक्षाएं, के बाद से इंटरफेस और वर्ग के उदाहरणों है स्थिर रुप से संपत्ति में जाना जाता है/सदस्य/विधि कुंजीहै, तो किसी भी घेरा में होता है "सुरक्षित स्थानों" की तरह संपत्ति के मूल्यया विधि पैरामीटर या वापसी प्रकार है ।
interface Interface<T> { val: T }
type X = Interface<X> // okay
class Class<T> { method(arg: T): void { } }
type Y = Class<Y> // okay
लेकिन सामान्य प्रकार फर्जी नाम वहाँ कोई नहीं है इस तरह की गारंटी देता है । प्रकार फर्जी नाम हो सकता है किसी भी संरचना है कि किसी भी गुमनाम हो सकता है प्रकार, तो संभावित घेरा है नहीं करने के लिए विवश पुनरावर्ती पेड़ की तरह की वस्तुओं:
type Safe<T> = { val: T };
type Unsafe<T> = T | { val: string };
जब संकलक instantiates एक जेनेरिक प्रकार है, यह defers अपने मूल्यांकन; यह तुरंत नहीं की कोशिश करने के लिए पूरी तरह से गणना के परिणामस्वरूप प्रकार है । यह सब देखता है रूप है:
type WouldBeSafe = Safe<WouldBeSafe>;
type WouldBeUnsafe = Unsafe<WouldBeUnsafe>;
उन दोनों के एक ही देखो करने के लिए संकलक... type X = SomeGenericTypeAlias<X>
. यह नहीं "देख" है कि WouldBeSafe
ठीक हो जाएगा:
//type WouldBeSafe = { val: WouldBeSafe }; // would be okay
जबकि WouldBeUnsafe
एक समस्या होगी:
//type WouldBeUnsafe = WouldBeUnsafe | { val: string }; // would be error
के बाद से यह अंतर नहीं देख सकते हैं, और क्योंकि कम से कम कुछ उपयोगों के लिए किया जाएगा अवैध रूप से परिपत्र, यह सिर्फ सभी पर प्रतिबंध लगाता है ।
तो, आप क्या कर सकते हैं? इस में से एक है, जहां उन मामलों मैं सुझाव है कि का उपयोग कर interface
के बजाय type
जब आप कर सकते हैं. आप कर सकते हैं अपने को फिर से लिखना record
प्रकार (इसे बदलने के लिए MyRecord
के लिए नेमिंग कन्वेंशन कारणों से) के रूप में एक interface
और सब कुछ काम करेंगे:
interface MyRecord<T> { val: T };
type B = MyRecord<B>; // okay
आप कर सकते हैं भी अपने को फिर से लिखना func
प्रकार (इसे बदलने के लिए Func
के लिए नेमिंग कन्वेंशन कारणों से फिर से) के रूप में एक interface
को बदलने के द्वारा समारोह प्रकार अभिव्यक्ति वाक्य रचना में एक हस्ताक्षर कॉल सिंटैक्स:
interface Func<T> { (arg: T): void }
type C = Func<C>; // okay
बेशक वहाँ रहे हैं स्थितियों जहाँ आप कर सकते हैं ऐसा नहीं है कि सीधे, इस तरह के रूप में में निर्मित Record
उपयोगिता प्रकार:
type Darn = Record<string, Darn>; // error
और आप नहीं कर सकते हैं, को फिर से लिखना मैप प्रकार Record
के रूप में एक interface
. और वास्तव में, यह असुरक्षित हो जाएगा की कोशिश करने के लिए बनाने के लिए कुंजी परिपत्र की तरह, type NoGood = Record<NoGood, string>
. यदि आप केवल करना चाहते हैं Record<string, T>
सामान्य के लिए T
, आप कर सकते हैं फिर से लिखना है कि के रूप में एक interface
:
interface Dictionary<T> extends Record<string, T> { };
type Works = Dictionary<Works>;
तो वहाँ अक्सर एक तरह का उपयोग करने के लिए एक interface
के बजाय type
अनुमति देने के लिए आप को व्यक्त करने के लिए "सुरक्षित" पुनरावर्ती प्रकार के ।
खेल का मैदान के लिए लिंक कोड