मुझे आश्चर्य है कि क्या टाइपस्क्रिप्ट में विशिष्ट उपप्रकारों में संघ प्रकारों को "विभाजित" करना संभव है। यह वह कोड है जिसका मैंने उपयोग करने का प्रयास किया है, यह स्पष्ट होना चाहिए कि मैं स्निपेट से क्या हासिल करने की कोशिश कर रहा हूं:

type SplitType<T> =
T extends (infer A)|(infer B)
? Something<A, B>
: T;

इस उदाहरण में Something<A, B> [A, B], या पूरी तरह से अलग प्रकार का हो सकता है। इसका मतलब यह होगा कि SplitType<string> सिर्फ एक string का उत्पादन करेगा, लेकिन SplitType<number|string> का मतलब [number, string] होगा।

क्या टाइपस्क्रिप्ट में ऐसा कुछ संभव है? और यदि नहीं, तो क्या कोई ऐसी सुविधा है जो भविष्य में इसकी अनुमति देगी (उदा. विभिन्न प्रकार ए>)?

2
m93a 22 अक्टूबर 2018, 16:54

1 उत्तर

सबसे बढ़िया उत्तर

यूनियन के सदस्यों की एक निश्चित अधिकतम संख्या के लिए, हम कॉल सिग्नेचर्स के इंटरसेक्शन को जेनरेट करके और फिर इसे मल्टीपल कॉल सिग्नेचर वाले टाइप से मैच करके यूनियन के सदस्यों को एक ही कार्यान्वयन-परिभाषित क्रम में निकाल सकते हैं। यह संस्करण केवल strictFunctionTypes सक्षम के साथ काम करता है।

// https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type UnionToFunctions<U> =
    U extends unknown ? (k: U) => void : never;

type IntersectionOfFunctionsToType<F> =
    F extends { (a: infer A): void; (b: infer B): void; (c: infer C): void; } ? [A, B, C] :
    F extends { (a: infer A): void; (b: infer B): void; } ? [A, B] :
    F extends { (a: infer A): void } ? [A] :
    never;

type SplitType<T> =
    IntersectionOfFunctionsToType<UnionToIntersection<UnionToFunctions<T>>>;

type Test1 = SplitType<number>;                    // [number]
type Test2 = SplitType<number | string>;           // [string, number]
type Test3 = SplitType<number | string | symbol>;  // [string, number, symbol]
6
Matt McCutchen 22 अक्टूबर 2018, 15:45