हम यहां पहुंच सकते हैं... ??
type Provider = \\\"PROVIDER A\\\" | \\\"PROVIDER B\\\";type ProviderAOpts = { ... };type ProviderBOpts = { ... };function connect( ...[provider, options]: | [\\\"PROVIDER A\\\", ProviderAOpts] | [\\\"PROVIDER B\\\", ProviderBOpts]) { switch (provider) { case \\\"PROVIDER A\\\": // options is ProviderAOpts ✅ case \\\"PROVIDER B\\\": // options is ProviderBOpts ✅ ... }}
connect(\\\"PROVIDER A\\\", { ... });connect(\\\"PROVIDER B\\\", { ... }); ^ autocomplete works ✅
तो बात यह है कि हम एक टुपल (सरणी) को ठीक उसी प्रकार से नष्ट कर रहे हैं जैसा हम चाहते हैं।
एकमात्र नकारात्मक पक्ष यह है कि यदि हम नख़रेबाज़ हैं, तो टुपल में और जोड़े जोड़ रहे हैं... हम यहां एक सामान्य प्रकार निकाल सकते हैं:
type Provider = \\\"PROVIDER A\\\" | \\\"PROVIDER B\\\";type ProviderAOpts = { ... };type ProviderBOpts = { ... };type ProviderOpts = { \\\"PROVIDER A\\\": ProviderAOpts; \\\"PROVIDER B\\\": ProviderBOpts;};// solves to // [\\\"PROVIDER A\\\", ProviderAOpts] | [\\\"PROVIDER B\\\", ProviderBOpts]type ConnectOptions = { [K in keyof ProviderOpts]: [K, ProviderOpts[K]];}[keyof ProviderOpts]; function connect(...[provider, options]: ConnectOptions) { switch (provider) { case \\\"PROVIDER A\\\": // options is ProviderAOpts ✅ case \\\"PROVIDER B\\\": // options is ProviderBOpts ✅ ... }}
connect(\\\"PROVIDER A\\\", { ... });connect(\\\"PROVIDER B\\\", { ... }); ^ autocomplete works ✅
type Provider = \\\"PROVIDER A\\\" | \\\"PROVIDER B\\\";type ProviderAOpts = { ... };type ProviderBOpts = { ... };type ProviderOpts = { \\\"PROVIDER A\\\": ProviderAOpts; \\\"PROVIDER B\\\": ProviderBOpts;};// aux type to extract the key and the options from ProviderOptstype KeyOpts= { [K in keyof T]: [K, T[K]];}[keyof T];function connect(...[provider, options]: KeyOpts ) { switch (provider) { case \\\"PROVIDER A\\\": // options is ProviderAOpts ✅ case \\\"PROVIDER B\\\": // options is ProviderBOpts ✅ ... }}
connect(\\\"PROVIDER A\\\", { ... });connect(\\\"PROVIDER B\\\", { ... }); ^ autocomplete works ✅
मदद के लिए माटुस्ज़ और लेन्ज़ को धन्यवाद?.
पढ़ने के लिए धन्यवाद ?।
","image":"http://www.luping.net/uploads/20241104/17307234156728be5752a02.jpg","datePublished":"2024-11-07T10:48:39+08:00","dateModified":"2024-11-07T10:48:39+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}एक परिदृश्य है जहां यह भावना विशेष रूप से तीव्र होती है: जब कोई फ़ंक्शन एक पैरामीटर लेता है जो इस पर निर्भर करता है कि कौन सा "मोड" सक्रिय है।
कुछ उदाहरण कोड के साथ स्पष्ट:
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; function connect(provider: Provider, options: ProviderAOpts | ProviderBOpts) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts case "PROVIDER B": // options is ProviderBOpts } }
(मैंने फू, गू, कुत्ता और बिल्ली के बजाय अधिक यथार्थवादी नामों का उपयोग करने की कोशिश की)।
यदि आपने टाइपस्क्रिप्ट के साथ कुछ समय बिताया है, तो आपको संदेह हो सकता है कि हम इसे ProviderAOpts के रूप में, ProviderBOpts के रूप में संभालते थे।
लेकिन एक समय ऐसा आता है जब आप मेज पर अपनी मुट्ठी पटकते हैं और दावा करते हैं: "अब और नहीं!"
इन मामलों में पहली बात जो हमेशा मेरे दिमाग में आती है वह है फ़ंक्शन ओवरलोडिंग का उपयोग करना:
function connect(provider: "PROVIDER A", options: ProviderAOpts): void; function connect(provider: "PROVIDER B", options: ProviderBOpts): void; function connect(provider: Provider, options: ProviderAOpts | ProviderBOpts) { switch (provider) { case "PROVIDER A": // (options as ProviderAOpts) ❌ case "PROVIDER B": // (options as ProviderBOpts) ❌ } }
जो काम नहीं करता। फ़ंक्शन हस्ताक्षर का सही अनुमान नहीं लगाया गया है. विकल्प पैरामीटर हमेशा ProviderAOpts | होता है प्रदाताबीओप्ट्स। जो आम संघ को हल करेगा।
Ts दोनों मापदंडों को सही ढंग से लिंक नहीं करता है।
अगला टूल जो मैं आज़माता हूं वह है टाइप प्रेडिकेट्स:
type ConnectOptions = ProviderAOpts | ProviderBOpts; function isAOptions(options: ConnectOptions): options is ProviderAOpts { return (options as ProviderAOpts).$$$ !== undefined; } function isBOptions(options: ConnectOptions): options is ProviderBOpts { return (options as ProviderBOpts).$$$ !== undefined; } function connect(provider: Provider, options: ConnectOptions) { switch (provider) { case "PROVIDER A": if (isAOptions(options)) { ... } case "PROVIDER B": if (isBOptions(options)) { ... } } ... }
लेकिन ईमानदारी से कहूं तो हमने कुछ भी हल नहीं किया। हमने बस इसे गलीचे के नीचे रख दिया? अतिरिक्त ifs पेश किया गया है और, हम अभी भी मापदंडों को लिंक नहीं कर रहे हैं।
जेनेरिक। मैंने पैरामीटर्स को लिंक करने के लिए जेनेरिक का उपयोग करने का प्रयास किया। काम नहीं करता:
function connect( provider: T, options: T extends "PROVIDER A" ? ProviderAOpts : ProviderBOpts ) { switch (provider) { case "PROVIDER A": // (options as ProviderAOpts) ❌ case "PROVIDER B": // (options as ProviderBOpts) ❌ } }
मैंने बहुत कोशिश की और यहां तक पहुंच गया
लेकिन अंत में, इससे कोई फर्क नहीं पड़ता
यह सब खोने के लिए मुझे गिरना पड़ा
लेकिन अंत में, इससे कोई फर्क नहीं पड़ता
??
प्रदाता प्रकार को जोड़ने वाले ऑप्ट पैरामीटर को संशोधित करना चाल है:
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderOptsBase = { provider: Provider; } type ProviderAOpts = ProviderOptsBase & { provider: "PROVIDER A"; ...; }; type ProviderBOpts = ProviderOptsBase & { provider: "PROVIDER B"; ...; }; function connect(options: ConnectOptions) { switch (options.provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ } }
यह सबसे आम समाधान है, लेकिन फ़ंक्शन हस्ताक्षर को बदलना हमेशा संभव नहीं होता है। या हो सकता है कि आप ऐसा नहीं चाहते हों। सिद्धांतों की बात?.
माटुस्ज़ बुर्जिन्स्की (@AndaristRake) और लेन्ज़ वेबर (@phry) को धन्यवाद
हम यहां पहुंच सकते हैं... ??
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; function connect( ...[provider, options]: | ["PROVIDER A", ProviderAOpts] | ["PROVIDER B", ProviderBOpts] ) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ ... } }
connect("PROVIDER A", { ... }); connect("PROVIDER B", { ... }); ^ autocomplete works ✅
तो बात यह है कि हम एक टुपल (सरणी) को ठीक उसी प्रकार से नष्ट कर रहे हैं जैसा हम चाहते हैं।
एकमात्र नकारात्मक पक्ष यह है कि यदि हम नख़रेबाज़ हैं, तो टुपल में और जोड़े जोड़ रहे हैं... हम यहां एक सामान्य प्रकार निकाल सकते हैं:
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; type ProviderOpts = { "PROVIDER A": ProviderAOpts; "PROVIDER B": ProviderBOpts; }; // solves to // ["PROVIDER A", ProviderAOpts] | ["PROVIDER B", ProviderBOpts] type ConnectOptions = { [K in keyof ProviderOpts]: [K, ProviderOpts[K]]; }[keyof ProviderOpts]; function connect(...[provider, options]: ConnectOptions) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ ... } }
connect("PROVIDER A", { ... }); connect("PROVIDER B", { ... }); ^ autocomplete works ✅
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; type ProviderOpts = { "PROVIDER A": ProviderAOpts; "PROVIDER B": ProviderBOpts; }; // aux type to extract the key and the options from ProviderOpts type KeyOpts= { [K in keyof T]: [K, T[K]]; }[keyof T]; function connect(...[provider, options]: KeyOpts ) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ ... } }
connect("PROVIDER A", { ... }); connect("PROVIDER B", { ... }); ^ autocomplete works ✅
मदद के लिए माटुस्ज़ और लेन्ज़ को धन्यवाद?.
पढ़ने के लिए धन्यवाद ?।
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3