टाइपस्क्रिप्ट 'infer' कीवर्ड के लिए एक व्यापक मार्गदर्शिका, शक्तिशाली प्रकार निष्कर्षण और हेरफेर के लिए सशर्त प्रकारों के साथ इसका उपयोग करने का तरीका बताती है, जिसमें उन्नत उपयोग के मामले भी शामिल हैं।
टाइपस्क्रिप्ट इन्फ़र में महारत हासिल करना: उन्नत प्रकार हेरफेर के लिए सशर्त प्रकार निष्कर्षण
टाइपस्क्रिप्ट की प्रकार प्रणाली अविश्वसनीय रूप से शक्तिशाली है, जो डेवलपर्स को मजबूत और बनाए रखने योग्य एप्लिकेशन बनाने की अनुमति देती है। इस शक्ति को सक्षम करने वाली प्रमुख विशेषताओं में से एक सशर्त प्रकारों के साथ संयोजन में उपयोग किया जाने वाला infer
कीवर्ड है। यह संयोजन जटिल प्रकार संरचनाओं से विशिष्ट प्रकारों को निकालने के लिए एक तंत्र प्रदान करता है। यह ब्लॉग पोस्ट infer
कीवर्ड में गहराई से उतरता है, इसकी कार्यक्षमता की व्याख्या करता है और उन्नत उपयोग के मामलों को प्रदर्शित करता है। हम विविध सॉफ़्टवेयर विकास परिदृश्यों पर लागू व्यावहारिक उदाहरणों का पता लगाएंगे, API इंटरैक्शन से लेकर जटिल डेटा संरचना हेरफेर तक।
सशर्त प्रकार क्या हैं?
infer
में गोता लगाने से पहले, आइए जल्दी से सशर्त प्रकारों की समीक्षा करें। टाइपस्क्रिप्ट में सशर्त प्रकार आपको जावास्क्रिप्ट में टर्नरी ऑपरेटर के समान एक शर्त के आधार पर एक प्रकार को परिभाषित करने की अनुमति देते हैं। मूल सिंटैक्स है:
T extends U ? X : Y
इसे इस प्रकार पढ़ा जाता है: "यदि प्रकार T
प्रकार U
को असाइन करने योग्य है, तो प्रकार X
है; अन्यथा, प्रकार Y
है।"
उदाहरण:
type IsString<T> = T extends string ? true : false;
type StringResult = IsString<string>; // type StringResult = true
type NumberResult = IsString<number>; // type NumberResult = false
infer
कीवर्ड का परिचय
infer
कीवर्ड का उपयोग सशर्त प्रकार के extends
क्लॉज के भीतर एक प्रकार चर घोषित करने के लिए किया जाता है जिसे जांचे जा रहे प्रकार से अनुमान लगाया जा सकता है। संक्षेप में, यह आपको बाद में उपयोग के लिए किसी प्रकार के भाग को "कैप्चर" करने की अनुमति देता है।
मूल सिंटैक्स:
type MyType<T> = T extends (infer U) ? U : never;
इस उदाहरण में, यदि T
कुछ प्रकार को असाइन करने योग्य है, तो टाइपस्क्रिप्ट U
के प्रकार का अनुमान लगाने का प्रयास करेगा। यदि अनुमान सफल होता है, तो प्रकार U
होगा; अन्यथा, यह never
होगा।
infer
के सरल उदाहरण
1. किसी फ़ंक्शन के रिटर्न टाइप का अनुमान लगाना
एक सामान्य उपयोग मामला किसी फ़ंक्शन के रिटर्न टाइप का अनुमान लगाना है:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
function add(a: number, b: number): number {
return a + b;
}
type AddReturnType = ReturnType<typeof add>; // type AddReturnType = number
function greet(name: string): string {
return `Hello, ${name}!`;
}
type GreetReturnType = ReturnType<typeof greet>; // type GreetReturnType = string
इस उदाहरण में, ReturnType<T>
एक फ़ंक्शन प्रकार T
को इनपुट के रूप में लेता है। यह जांचता है कि क्या T
किसी ऐसे फ़ंक्शन को असाइन करने योग्य है जो कोई भी तर्क स्वीकार करता है और एक मान लौटाता है। यदि ऐसा है, तो यह रिटर्न प्रकार को R
के रूप में अनुमान लगाता है और इसे लौटाता है। अन्यथा, यह any
लौटाता है।
2. सरणी तत्व प्रकार का अनुमान लगाना
एक और उपयोगी परिदृश्य एक सरणी से तत्व प्रकार को निकालना है:
type ArrayElementType<T> = T extends (infer U)[] ? U : never;
type NumberArrayType = ArrayElementType<number[]>; // type NumberArrayType = number
type StringArrayType = ArrayElementType<string[]>; // type StringArrayType = string
type MixedArrayType = ArrayElementType<(string | number)[]>; // type MixedArrayType = string | number
type NotAnArrayType = ArrayElementType<number>; // type NotAnArrayType = never
यहां, ArrayElementType<T>
जांचता है कि क्या T
एक सरणी प्रकार है। यदि ऐसा है, तो यह तत्व प्रकार को U
के रूप में अनुमान लगाता है और इसे लौटाता है। यदि नहीं, तो यह never
लौटाता है।
infer
के उन्नत उपयोग के मामले
1. किसी कंस्ट्रक्टर के पैरामीटर का अनुमान लगाना
आप किसी कंस्ट्रक्टर फ़ंक्शन के पैरामीटर प्रकारों को निकालने के लिए infer
का उपयोग कर सकते हैं:
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
class Person {
constructor(public name: string, public age: number) {}
}
type PersonConstructorParams = ConstructorParameters<typeof Person>; // type PersonConstructorParams = [string, number]
class Point {
constructor(public x: number, public y: number) {}
}
type PointConstructorParams = ConstructorParameters<typeof Point>; // type PointConstructorParams = [number, number]
इस मामले में, ConstructorParameters<T>
एक कंस्ट्रक्टर फ़ंक्शन प्रकार T
लेता है। यह कंस्ट्रक्टर पैरामीटर के प्रकारों को P
के रूप में अनुमान लगाता है और उन्हें एक टपल के रूप में लौटाता है।
2. ऑब्जेक्ट प्रकारों से गुण निकालना
infer
का उपयोग मैप्ड प्रकारों और सशर्त प्रकारों का उपयोग करके ऑब्जेक्ट प्रकारों से विशिष्ट गुणों को निकालने के लिए भी किया जा सकता है:
type PickByType<T, K extends keyof T, U> = {
[P in K as T[P] extends U ? P : never]: T[P];
};
interface User {
id: number;
name: string;
age: number;
email: string;
isActive: boolean;
}
type StringProperties = PickByType<User, keyof User, string>; // type StringProperties = { name: string; email: string; }
type NumberProperties = PickByType<User, keyof User, number>; // type NumberProperties = { id: number; age: number; }
//An interface representing geographic coordinates.
interface GeoCoordinates {
latitude: number;
longitude: number;
altitude: number;
country: string;
city: string;
timezone: string;
}
type NumberCoordinateProperties = PickByType<GeoCoordinates, keyof GeoCoordinates, number>; // type NumberCoordinateProperties = { latitude: number; longitude: number; altitude: number; }
यहां, PickByType<T, K, U>
एक नया प्रकार बनाता है जिसमें केवल T
(K
में कुंजियों के साथ) के गुण शामिल हैं जिनके मान प्रकार U
को असाइन करने योग्य हैं। मैप्ड प्रकार T
की कुंजियों पर पुनरावृति करता है, और सशर्त प्रकार उन कुंजियों को फ़िल्टर करता है जो निर्दिष्ट प्रकार से मेल नहीं खाते हैं।
3. वादों के साथ काम करना
आप एक Promise
के समाधान प्रकार का अनुमान लगा सकते हैं:
type Awaited<T> = T extends Promise<infer U> ? U : T;
async function fetchData(): Promise<string> {
return 'API से डेटा';
}
type FetchDataType = Awaited<ReturnType<typeof fetchData>>; // type FetchDataType = string
async function fetchNumbers(): Promise<number[]> {
return [1, 2, 3];
}
type FetchedNumbersType = Awaited<ReturnType<typeof fetchNumbers>>; //type FetchedNumbersType = number[]
Awaited<T>
प्रकार एक प्रकार T
लेता है, जो एक Promise होने की उम्मीद है। फिर प्रकार Promise के समाधान प्रकार U
का अनुमान लगाता है, और इसे लौटाता है। यदि T
एक Promise नहीं है, तो यह T लौटाता है। यह टाइपस्क्रिप्ट के नए संस्करणों में एक अंतर्निहित यूटिलिटी प्रकार है।
4. वादों की सरणी के प्रकार को निकालना
Awaited
और सरणी प्रकार अनुमान को मिलाकर आप वादों की सरणी द्वारा हल किए गए प्रकार का अनुमान लगा सकते हैं। यह Promise.all
से निपटने पर विशेष रूप से उपयोगी है।
type PromiseArrayReturnType<T extends Promise<any>[]> = {
[K in keyof T]: Awaited<T[K]>;
};
async function getUSDRate(): Promise<number> {
return 0.0069;
}
async function getEURRate(): Promise<number> {
return 0.0064;
}
const rates = [getUSDRate(), getEURRate()];
type RatesType = PromiseArrayReturnType<typeof rates>;
// type RatesType = [number, number]
यह उदाहरण पहले दो अतुल्यकालिक फ़ंक्शन, getUSDRate
और getEURRate
को परिभाषित करता है, जो विनिमय दरों को लाने का अनुकरण करते हैं। फिर PromiseArrayReturnType
यूटिलिटी प्रकार सरणी में प्रत्येक Promise
से समाधान प्रकार निकालता है, जिसके परिणामस्वरूप एक टपल प्रकार होता है जहां प्रत्येक तत्व संबंधित Promise का प्रतीक्षित प्रकार होता है।
विभिन्न डोमेन में व्यावहारिक उदाहरण
1. ई-कॉमर्स एप्लिकेशन
एक ई-कॉमर्स एप्लिकेशन पर विचार करें जहां आप एपीआई से उत्पाद विवरण प्राप्त करते हैं। आप उत्पाद डेटा के प्रकार को निकालने के लिए infer
का उपयोग कर सकते हैं:
interface Product {
id: number;
name: string;
price: number;
description: string;
imageUrl: string;
category: string;
rating: number;
countryOfOrigin: string;
}
async function fetchProduct(productId: number): Promise<Product> {
// एपीआई कॉल का अनुकरण करें
return new Promise((resolve) => {
setTimeout(() => {
resolve({
id: productId,
name: 'उदाहरण उत्पाद',
price: 29.99,
description: 'एक नमूना उत्पाद',
imageUrl: 'https://example.com/image.jpg',
category: 'इलेक्ट्रॉनिक्स',
rating: 4.5,
countryOfOrigin: 'कनाडा'
});
}, 500);
});
}
type ProductType = Awaited<ReturnType<typeof fetchProduct>>; // type ProductType = Product
function displayProductDetails(product: ProductType) {
console.log(`उत्पाद का नाम: ${product.name}`);
console.log(`कीमत: ${product.price} ${product.countryOfOrigin === 'कनाडा' ? 'CAD' : (product.countryOfOrigin === 'USA' ? 'USD' : 'EUR')}`);
}
fetchProduct(123).then(displayProductDetails);
इस उदाहरण में, हम एक Product
इंटरफ़ेस और एक fetchProduct
फ़ंक्शन को परिभाषित करते हैं जो एपीआई से उत्पाद विवरण प्राप्त करता है। हम Awaited
और ReturnType
का उपयोग fetchProduct
फ़ंक्शन के रिटर्न प्रकार से Product
प्रकार को निकालने के लिए करते हैं, जिससे हमें displayProductDetails
फ़ंक्शन को टाइप-चेक करने की अनुमति मिलती है।
2. अंतर्राष्ट्रीयकरण (i18n)
मान लीजिए कि आपके पास एक अनुवाद फ़ंक्शन है जो लोकेल के आधार पर अलग-अलग स्ट्रिंग लौटाता है। आप प्रकार सुरक्षा के लिए इस फ़ंक्शन के रिटर्न प्रकार को निकालने के लिए infer
का उपयोग कर सकते हैं:
interface Translations {
greeting: string;
farewell: string;
welcomeMessage: (name: string) => string;
}
const enTranslations: Translations = {
greeting: 'नमस्ते',
farewell: 'अलविदा',
welcomeMessage: (name: string) => `स्वागत है, ${name}!`,
};
const frTranslations: Translations = {
greeting: 'बोनजोर',
farewell: 'ऑ रेवॉयर',
welcomeMessage: (name: string) => `बिएनवेन्यू, ${name}!`,
};
function getTranslation(locale: 'en' | 'fr'): Translations {
return locale === 'en' ? enTranslations : frTranslations;
}
type TranslationType = ReturnType<typeof getTranslation>;
function greetUser(locale: 'en' | 'fr', name: string) {
const translations = getTranslation(locale);
console.log(translations.welcomeMessage(name));
}
greetUser('fr', 'जीन'); // आउटपुट: बिएनवेन्यू, जीन!
यहां, TranslationType
को Translations
इंटरफ़ेस होने का अनुमान लगाया गया है, यह सुनिश्चित करते हुए कि greetUser
फ़ंक्शन में अनुवादित स्ट्रिंग तक पहुंचने के लिए सही प्रकार की जानकारी है।
3. एपीआई प्रतिक्रिया हैंडलिंग
एपीआई के साथ काम करते समय, प्रतिक्रिया संरचना जटिल हो सकती है। infer
नेस्टेड एपीआई प्रतिक्रियाओं से विशिष्ट डेटा प्रकारों को निकालने में मदद कर सकता है:
interface ApiResponse<T> {
status: number;
data: T;
message?: string;
}
interface UserData {
id: number;
username: string;
email: string;
profile: {
firstName: string;
lastName: string;
country: string;
language: string;
}
}
async function fetchUser(userId: number): Promise<ApiResponse<UserData>> {
// एपीआई कॉल का अनुकरण करें
return new Promise((resolve) => {
setTimeout(() => {
resolve({
status: 200,
data: {
id: userId,
username: 'johndoe',
email: 'john.doe@example.com',
profile: {
firstName: 'जॉन',
lastName: 'डो',
country: 'यूएसए',
language: 'en'
}
}
});
}, 500);
});
}
type UserApiResponse = Awaited<ReturnType<typeof fetchUser>>;
type UserProfileType = UserApiResponse['data']['profile'];
function displayUserProfile(profile: UserProfileType) {
console.log(`नाम: ${profile.firstName} ${profile.lastName}`);
console.log(`देश: ${profile.country}`);
}
fetchUser(123).then((response) => {
if (response.status === 200) {
displayUserProfile(response.data.profile);
}
});
इस उदाहरण में, हम एक ApiResponse
इंटरफ़ेस और एक UserData
इंटरफ़ेस को परिभाषित करते हैं। हम एपीआई प्रतिक्रिया से UserProfileType
निकालने के लिए infer
और प्रकार इंडेक्सिंग का उपयोग करते हैं, यह सुनिश्चित करते हुए कि displayUserProfile
फ़ंक्शन को सही प्रकार प्राप्त हो।
infer
का उपयोग करने के लिए सर्वोत्तम अभ्यास
- इसे सरल रखें:
infer
का उपयोग केवल तभी करें जब आवश्यक हो। इसका अधिक उपयोग करने से आपका कोड पढ़ना और समझना कठिन हो सकता है। - अपने प्रकारों का दस्तावेजीकरण करें: यह समझाने के लिए टिप्पणियाँ जोड़ें कि आपके सशर्त प्रकार और
infer
कथन क्या कर रहे हैं। - अपने प्रकारों का परीक्षण करें: यह सुनिश्चित करने के लिए टाइपस्क्रिप्ट के प्रकार जांच का उपयोग करें कि आपके प्रकार अपेक्षा के अनुरूप व्यवहार कर रहे हैं।
- प्रदर्शन पर विचार करें: जटिल सशर्त प्रकार कभी-कभी संकलन समय को प्रभावित कर सकते हैं। अपने प्रकारों की जटिलता के प्रति सचेत रहें।
- यूटिलिटी प्रकारों का उपयोग करें: टाइपस्क्रिप्ट कई अंतर्निहित यूटिलिटी प्रकार (जैसे,
ReturnType
,Awaited
) प्रदान करता है जो आपके कोड को सरल बना सकते हैं और कस्टमinfer
स्टेटमेंट की आवश्यकता को कम कर सकते हैं।
सामान्य कमियां
- गलत अनुमान: कभी-कभी, टाइपस्क्रिप्ट एक ऐसे प्रकार का अनुमान लगा सकता है जो आपकी अपेक्षा के अनुरूप नहीं है। अपनी प्रकार परिभाषाओं और शर्तों की दोबारा जांच करें।
- परिपत्र निर्भरताएँ:
infer
का उपयोग करके पुनरावर्ती प्रकारों को परिभाषित करते समय सावधान रहें, क्योंकि वे परिपत्र निर्भरताएँ और संकलन त्रुटियाँ उत्पन्न कर सकते हैं। - अति जटिल प्रकार: अत्यधिक जटिल सशर्त प्रकार बनाने से बचें जिन्हें समझना और बनाए रखना मुश्किल है। उन्हें छोटे, अधिक प्रबंधनीय प्रकारों में तोड़ें।
infer
के विकल्प
जबकि infer
एक शक्तिशाली उपकरण है, ऐसी स्थितियाँ हैं जहाँ वैकल्पिक दृष्टिकोण अधिक उपयुक्त हो सकते हैं:
- प्रकार अभिकथन: कुछ मामलों में, आप किसी मान के प्रकार को स्पष्ट रूप से निर्दिष्ट करने के लिए प्रकार अभिकथन का उपयोग कर सकते हैं, बजाय इसके कि इसका अनुमान लगाया जाए। हालाँकि, प्रकार अभिकथन के साथ सावधान रहें, क्योंकि वे प्रकार जाँच को दरकिनार कर सकते हैं।
- प्रकार गार्ड: प्रकार गार्ड का उपयोग रनटाइम जांच के आधार पर किसी मान के प्रकार को कम करने के लिए किया जा सकता है। यह तब उपयोगी होता है जब आपको रनटाइम स्थितियों के आधार पर विभिन्न प्रकारों को संभालने की आवश्यकता होती है।
- यूटिलिटी प्रकार: टाइपस्क्रिप्ट कस्टम
infer
स्टेटमेंट की आवश्यकता के बिना कई सामान्य प्रकार हेरफेर कार्यों को संभालने वाले यूटिलिटी प्रकारों का एक समृद्ध सेट प्रदान करता है।
निष्कर्ष
टाइपस्क्रिप्ट में infer
कीवर्ड, जब सशर्त प्रकारों के साथ जोड़ा जाता है, तो उन्नत प्रकार हेरफेर क्षमताओं को अनलॉक करता है। यह आपको जटिल प्रकार संरचनाओं से विशिष्ट प्रकारों को निकालने की अनुमति देता है, जिससे आप अधिक मजबूत, बनाए रखने योग्य और प्रकार-सुरक्षित कोड लिख सकते हैं। फ़ंक्शन रिटर्न प्रकारों का अनुमान लगाने से लेकर ऑब्जेक्ट प्रकारों से गुणों को निकालने तक, संभावनाएँ विशाल हैं। इस गाइड में बताए गए सिद्धांतों और सर्वोत्तम प्रथाओं को समझकर, आप infer
का पूरी क्षमता से लाभ उठा सकते हैं और अपने टाइपस्क्रिप्ट कौशल को बढ़ा सकते हैं। अपने प्रकारों का दस्तावेजीकरण करना, उनका अच्छी तरह से परीक्षण करना और उपयुक्त होने पर वैकल्पिक दृष्टिकोणों पर विचार करना याद रखें। infer
में महारत हासिल करने से आप वास्तव में अभिव्यंजक और शक्तिशाली टाइपस्क्रिप्ट कोड लिख सकते हैं, जिसके परिणामस्वरूप अंततः बेहतर सॉफ़्टवेयर बनता है।