इसे कैसे प्राप्त किया जा सकता है ?

type Fruit = "apple" | 'banana' | 'coconut'

type FruitCollection = { [f in Fruit]?: number }

const validFruitCollection: FruitCollection = { apple: 1, coconut: 2 } 

const emptyCollectionShouldNotPass: FruitCollection = {} // I don't want typescript to let this pass
2
Lev 20 मार्च 2020, 14:16
 – 
Murat Karagöz
20 मार्च 2020, 14:21
यह उत्तर ठीक वही है जो आप चाहते हैं stackoverflow.com/a/49725198/4467208
 – 
Murat Karagöz
20 मार्च 2020, 14:21
 – 
Murat Karagöz
20 मार्च 2020, 14:22
मूरत अंतर यहाँ है कि इन उदाहरणों में प्रकार निर्धारित होते हैं, यहाँ हमारे पास बहुत ढीले प्रकार हैं। इसका मतलब है कि हम यह नहीं चुन सकते कि वास्तव में क्या रहना चाहिए
 – 
Maciej Sikora
20 मार्च 2020, 14:33

2 जवाब

हमें जो चाहिए वह टाइप है जो खाली वस्तु की संभावना को बाहर कर देगा। इसे प्राप्त करने के लिए हमें उपयोगिता प्रकार और मूल्य निर्माता की आवश्यकता है। विचार करना:

type Fruit = "apple" | 'banana' | 'coconut'

type FruitCollection = { [f in Fruit]?: number }

// type which will exclude empty object
type NotEmpty<T> = {} extends T ? never : T

// value constructor
const makeFruitCollection = <T extends FruitCollection>(c: NotEmpty<T>) => c; 

// use cases
const validFruitCollection = makeFruitCollection({ apple: 1, coconut: 2 }) // ok 👌
const emptyCollectionShouldNotPass = makeFruitCollection({}) // error 👌

टाइप NotEmpty जांच कर रहा है कि क्या हमारा T जो पहले से ही FruitCollection की सभी जरूरतों को पूरा कर चुका है, खाली वस्तु नहीं है, अगर हमें never मिलता है, और प्रकार का कोई मूल्य नहीं है never {} के साथ फ़ंक्शन का उपयोग करने के लिए संकलित नहीं होगा।

क्रीड़ास्थल

4
Maciej Sikora 20 मार्च 2020, 14:28
1
यदि आप किसी फ़ंक्शन का उपयोग कर रहे हैं, तो यह एक अच्छा विकल्प है, इस समाधान के साथ सामान्य समस्या यह है कि प्रकार को कम से कम एक संपत्ति की आवश्यकता नहीं होती है, इसलिए आप उन चरों के साथ समाप्त हो सकते हैं जो बाधा का सम्मान नहीं करते हैं। लेकिन फ़ंक्शन पैरामीटर के लिए यह समाधान को समझने के लिए एक अच्छा, तर्कसंगत रूप से आसान है :)
 – 
Titian Cernicova-Dragomir
20 मार्च 2020, 14:44
एक अंतर्निहित उपयोगिता प्रकार है: बहिष्कृत करें। इस प्रकार NotEmpty<T> को Exclude<T, {}> के रूप में फिर से लिखा जा सकता है?
 – 
weakish
24 मई 2020, 11:54

आप सभी संपत्तियों के संघ के साथ सभी वैकल्पिक सदस्यों के साथ प्रकार को प्रतिच्छेद कर सकते हैं, जहां संघ के प्रत्येक घटक में, एक सदस्य की आवश्यकता होती है। तो मूल रूप से आपके पास होगा:


type WhatWeWant = {
    apple?: number | undefined;
    banana?: number | undefined;
    coconut?: number | undefined;
} & (
    | { apple: number; }
    | { banana: number; }
    | { coconut : number ;})

इस प्रकार को बिना लिखे प्राप्त करने के लिए हम एक मैप किए गए प्रकार का उपयोग कर सकते हैं:


type RequireOne<T> = T & { [P in keyof T]: Required<Pick<T, P>> }[keyof T]
type FruitCollection = RequireOne<{ [f in Fruit]?: number }>

खेल का मैदान लिंक

RequireOne में मैप किए गए प्रकार का विचार उपरोक्त WhatWeWant प्रकार में संघ बनाना है (T मूल प्रकार होगा जो वैकल्पिक गुण होंगे)। तो हम क्या करते हैं, मैप किए गए प्रकार में हम प्रत्येक संपत्ति को T में लेते हैं और इसे Required<Pick<T, P>> के रूप में टाइप करते हैं। इसका मतलब है कि प्रत्येक कुंजी के लिए, हमें एक प्रकार मिलता है जिसमें केवल वह कुंजी होती है, उदाहरण के लिए मूल रूप से इस प्रकार:

{
  apple: { apple: number; }
  banana: { banana: number; }
  coconut: { coconut: number ;}
}

इस प्रकार के साथ, हम जो संघ चाहते हैं उसे प्राप्त करने की बात केवल keyof T को अनुक्रमणित करने की बात है, ताकि हमारी वस्तु में सभी प्रकार की संपत्ति का एक संघ प्राप्त हो सके।

2
Titian Cernicova-Dragomir 20 मार्च 2020, 17:10
एक स्पष्टीकरण जोड़ा, अगर आपको और विवरण चाहिए तो मुझे बताएं
 – 
Titian Cernicova-Dragomir
20 मार्च 2020, 17:10
बहुत धन्यवाद। यह देखने की कोशिश कर रहा हूं कि क्या मेरा पोर सिर अब मिल गया है।
 – 
Lev
20 मार्च 2020, 17:15