क्यों टाइपप्रति की अनुमति नहीं परिपत्र संदर्भ में जेनरिक?

0

सवाल

यहाँ के उदाहरण हैं, जहां प्रकार सीधे संदर्भ में ही अपनी परिभाषा है, लेकिन जब अनमना के माध्यम से एक सामान्य यह पूरी तरह से विफल रहता है ।

type a = { val: a }; // <-- doesn't care about circular references!

type record<T> = { val: T };

type b = record<b>; // <-- doesn't work!

type func<T> = (arg: T) => void;

type c = func<c>; // <-- doesn't work!

type d = (arg: d) => void; // <-- works!?
types typescript
2021-11-23 20:48:45
2

सबसे अच्छा जवाब

3

देखें 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 अनुमति देने के लिए आप को व्यक्त करने के लिए "सुरक्षित" पुनरावर्ती प्रकार के ।

खेल का मैदान के लिए लिंक कोड

2021-11-23 21:31:48

धन्यवाद! इस शांत और उपयोगी!
radiish
1

चलो काटना इन परिदृश्य की एक एक करके.

परिदृश्य 1

type a = { val: a }; // <-- doesn't care about circular references!

यह दिलचस्प है इस की अनुमति दी है । मैं देख नहीं कैसे आप में सक्षम हो सकता है करने के लिए एक उदाहरण के निर्माण को संतुष्ट होता है कि इस प्रकार है:

const A: a = {
  val: {
    val: {
      // It will always error out at the most inner node.
    }
  }
}

परिदृश्य 2

type record<T> = { val: T };

यह नहीं है एक परिपत्र संदर्भ और संतुष्ट किया जा सकता है इस तरह:

const B: record<string> = {
  val: "test"
}

परिदृश्य 3

type b = record<b>; // <-- doesn't work!

यह मुझे समझ में आता है कि यह काम नहीं करता है. में 1 परिदृश्य में, वहाँ होगा कोई रास्ता नहीं करने के लिए एक उदाहरण के निर्माण को संतुष्ट करता है कि इस बाधा.

परिदृश्य 4

type func<T> = (arg: T) => void;

यह नहीं है एक परिपत्र संदर्भ और संतुष्ट किया जा सकता है इस तरह:

const C: func<string> = (arg: string) => {}

परिदृश्य 5

type c = func<c>; // <-- doesn't work!

यह मुझे समझ में आता है कि यह काम नहीं करता है. में 1 परिदृश्य में, वहाँ होगा कोई रास्ता नहीं करने के लिए एक उदाहरण के निर्माण को संतुष्ट करता है कि इस बाधा.

परिदृश्य 6

type d = (arg: d) => void; // <-- works!?

मैं कर सकते हैं वास्तव में एक समारोह में लिखने को संतुष्ट करने के लिए इस बाधा है, लेकिन मैं नहीं हूँ यकीन है कि यह क्या हो रहा है मुझे:

const D: d = (arg) => {}
D(D)
2021-11-23 21:34:19

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में