टाइपस्क्रिप्ट 'infer' कीवर्डसाठी एक सर्वसमावेशक मार्गदर्शक. शक्तिशाली प्रकार काढण्यासाठी आणि हाताळणीसाठी कंडिशनल टाइपसह त्याचा वापर कसा करावा, हे प्रगत उदाहरणांसह स्पष्ट केले आहे.
टाइपस्क्रिप्ट इन्फरवर प्रभुत्व मिळवा: प्रगत प्रकार हाताळणीसाठी कंडिशनल टाइप एक्सट्रॅक्शन
टाइपस्क्रिप्टची टाइप सिस्टीम खूप शक्तिशाली आहे, ज्यामुळे डेव्हलपर्सना मजबूत आणि सुलभ ॲप्लिकेशन्स तयार करता येतात. या शक्तीला सक्षम करणारे एक महत्त्वाचे वैशिष्ट्य म्हणजे infer
कीवर्ड, जो कंडिशनल टाइप्ससोबत वापरला जातो. हे संयोजन क्लिष्ट टाइप स्ट्रक्चर्समधून विशिष्ट टाइप काढण्याची यंत्रणा प्रदान करते. हा ब्लॉग पोस्ट infer
कीवर्डचा सखोल अभ्यास करतो, त्याची कार्यक्षमता स्पष्ट करतो आणि प्रगत वापराची उदाहरणे दाखवतो. आम्ही एपीआय इंटरॅक्शनपासून ते क्लिष्ट डेटा स्ट्रक्चर मॅनिप्युलेशनपर्यंत, विविध सॉफ्टवेअर डेव्हलपमेंट परिस्थितींसाठी लागू होणारी व्यावहारिक उदाहरणे शोधू.
कंडिशनल टाइप्स काय आहेत?
आपण 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
क्लॉजमध्ये एक टाइप व्हेरिएबल घोषित करण्यासाठी वापरला जातो जो तपासल्या जाणाऱ्या टाइपमधून अनुमानित (infer) केला जाऊ शकतो. थोडक्यात, हे आपल्याला नंतरच्या वापरासाठी टाइपचा एक भाग "कॅप्चर" करण्याची परवानगी देते.
मूळ सिंटॅक्स:
type MyType<T> = T extends (infer U) ? U : never;
या उदाहरणात, जर T
कोणत्यातरी टाइपला नियुक्त करण्यायोग्य असेल, तर टाइपस्क्रिप्ट U
चा टाइप अनुमानित करण्याचा प्रयत्न करेल. जर अनुमान यशस्वी झाले, तर टाइप U
असेल; अन्यथा, तो never
असेल.
infer
ची साधी उदाहरणे
१. फंक्शनचा रिटर्न टाइप अनुमानित करणे
फंक्शनचा रिटर्न टाइप अनुमानित करणे हा एक सामान्य वापर आहे:
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
परत करते.
२. ॲरे एलिमेंटचा टाइप अनुमानित करणे
ॲरेमधून एलिमेंटचा टाइप काढणे हे आणखी एक उपयुक्त उदाहरण आहे:
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
चे प्रगत वापर
१. कन्स्ट्रक्टरचे पॅरामीटर्स अनुमानित करणे
आपण कन्स्ट्रक्टर फंक्शनचे पॅरामीटर टाइप काढण्यासाठी 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
म्हणून अनुमानित करते आणि त्यांना टपल (tuple) म्हणून परत करते.
२. ऑब्जेक्ट टाइपमधून प्रॉपर्टीज काढणे
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
च्या कीजवर पुनरावृत्ती करतो आणि कंडिशनल टाइप निर्दिष्ट टाइपशी जुळत नसलेल्या कीज फिल्टर करतो.
३. प्रॉमिसेससोबत काम करणे
आपण Promise
चा रिझॉल्व्ह केलेला टाइप अनुमानित करू शकता:
type Awaited<T> = T extends Promise<infer U> ? U : T;
async function fetchData(): Promise<string> {
return 'Data from 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
टाइप घेते, जो एक प्रॉमिस असण्याची अपेक्षा असते. त्यानंतर टाइप प्रॉमिसचा रिझॉल्व्ह केलेला टाइप U
अनुमानित करतो आणि तो परत करतो. जर T
प्रॉमिस नसेल, तर तो T परत करतो. हा टाइपस्क्रिप्टच्या नवीन आवृत्त्यांमध्ये एक अंगभूत युटिलिटी टाइप आहे.
४. प्रॉमिसेसच्या ॲरेचा टाइप काढणे
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
मधून रिझॉल्व्ह केलेला टाइप काढतो, ज्यामुळे एक टपल टाइप तयार होतो जिथे प्रत्येक घटक संबंधित प्रॉमिसचा अवेटेड (awaited) टाइप असतो.
विविध क्षेत्रांमधील व्यावहारिक उदाहरणे
१. ई-कॉमर्स ॲप्लिकेशन
एका ई-कॉमर्स ॲप्लिकेशनचा विचार करा जिथे आपण API मधून उत्पादनाची माहिती मिळवता. आपण उत्पादनाच्या डेटाचा टाइप काढण्यासाठी 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> {
// Simulate API call
return new Promise((resolve) => {
setTimeout(() => {
resolve({
id: productId,
name: 'Example Product',
price: 29.99,
description: 'A sample product',
imageUrl: 'https://example.com/image.jpg',
category: 'Electronics',
rating: 4.5,
countryOfOrigin: 'Canada'
});
}, 500);
});
}
type ProductType = Awaited<ReturnType<typeof fetchProduct>>; // type ProductType = Product
function displayProductDetails(product: ProductType) {
console.log(`Product Name: ${product.name}`);
console.log(`Price: ${product.price} ${product.countryOfOrigin === 'Canada' ? 'CAD' : (product.countryOfOrigin === 'USA' ? 'USD' : 'EUR')}`);
}
fetchProduct(123).then(displayProductDetails);
या उदाहरणात, आम्ही एक Product
इंटरफेस आणि एक fetchProduct
फंक्शन परिभाषित करतो जे API मधून उत्पादनाची माहिती मिळवते. आम्ही fetchProduct
फंक्शनच्या रिटर्न टाइपमधून Product
टाइप काढण्यासाठी Awaited
आणि ReturnType
वापरतो, ज्यामुळे आम्हाला displayProductDetails
फंक्शनची टाइप-तपासणी करता येते.
२. आंतरराष्ट्रीयीकरण (i18n)
समजा तुमच्याकडे एक भाषांतर फंक्शन आहे जे लोकॅलच्या आधारावर वेगवेगळे स्ट्रिंग्स परत करते. तुम्ही टाइप सुरक्षिततेसाठी या फंक्शनचा रिटर्न टाइप काढण्यासाठी infer
वापरू शकता:
interface Translations {
greeting: string;
farewell: string;
welcomeMessage: (name: string) => string;
}
const enTranslations: Translations = {
greeting: 'Hello',
farewell: 'Goodbye',
welcomeMessage: (name: string) => `Welcome, ${name}!`,
};
const frTranslations: Translations = {
greeting: 'Bonjour',
farewell: 'Au revoir',
welcomeMessage: (name: string) => `Bienvenue, ${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', 'Jean'); // Output: Bienvenue, Jean!
येथे, TranslationType
हा Translations
इंटरफेस म्हणून अनुमानित केला जातो, ज्यामुळे greetUser
फंक्शनकडे भाषांतरित स्ट्रिंग्स ॲक्सेस करण्यासाठी योग्य टाइपची माहिती असते याची खात्री होते.
३. API रिस्पॉन्स हाताळणी
APIs सोबत काम करताना, रिस्पॉन्सची रचना क्लिष्ट असू शकते. infer
नेस्टेड API रिस्पॉन्समधून विशिष्ट डेटा टाइप काढण्यास मदत करू शकते:
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>> {
// Simulate API call
return new Promise((resolve) => {
setTimeout(() => {
resolve({
status: 200,
data: {
id: userId,
username: 'johndoe',
email: 'john.doe@example.com',
profile: {
firstName: 'John',
lastName: 'Doe',
country: 'USA',
language: 'en'
}
}
});
}, 500);
});
}
type UserApiResponse = Awaited<ReturnType<typeof fetchUser>>;
type UserProfileType = UserApiResponse['data']['profile'];
function displayUserProfile(profile: UserProfileType) {
console.log(`Name: ${profile.firstName} ${profile.lastName}`);
console.log(`Country: ${profile.country}`);
}
fetchUser(123).then((response) => {
if (response.status === 200) {
displayUserProfile(response.data.profile);
}
});
या उदाहरणात, आम्ही एक ApiResponse
इंटरफेस आणि एक UserData
इंटरफेस परिभाषित करतो. आम्ही API रिस्पॉन्समधून UserProfileType
काढण्यासाठी infer
आणि टाइप इंडेक्सिंग वापरतो, ज्यामुळे displayUserProfile
फंक्शनला योग्य टाइप मिळतो याची खात्री होते.
infer
वापरण्यासाठी सर्वोत्तम पद्धती
- सोपे ठेवा:
infer
फक्त आवश्यक असेल तेव्हाच वापरा. त्याचा अतिवापर केल्याने तुमचा कोड वाचायला आणि समजायला कठीण होऊ शकतो. - तुमच्या टाइप्सचे दस्तऐवजीकरण करा: तुमचे कंडिशनल टाइप्स आणि
infer
स्टेटमेंट्स काय करत आहेत हे स्पष्ट करण्यासाठी टिप्पण्या जोडा. - तुमचे टाइप्स तपासा: तुमचे टाइप्स अपेक्षेप्रमाणे वागत आहेत याची खात्री करण्यासाठी टाइपस्क्रिप्टची टाइप तपासणी वापरा.
- कार्यक्षमतेचा विचार करा: क्लिष्ट कंडिशनल टाइप्स कधीकधी संकलन वेळेवर परिणाम करू शकतात. तुमच्या टाइप्सच्या गुंतागुंतीबद्दल जागरूक रहा.
- युटिलिटी टाइप्स वापरा: टाइपस्क्रिप्ट अनेक अंगभूत युटिलिटी टाइप्स (उदा.,
ReturnType
,Awaited
) प्रदान करते जे तुमचा कोड सोपा करू शकतात आणि सानुकूलinfer
स्टेटमेंट्सची गरज कमी करू शकतात.
सामान्य चुका
- चुकीचे अनुमान: कधीकधी, टाइपस्क्रिप्ट असा टाइप अनुमानित करू शकते जो तुमच्या अपेक्षेप्रमाणे नसतो. तुमच्या टाइप व्याख्या आणि अटी पुन्हा तपासा.
- चक्रीय अवलंबित्व (Circular Dependencies):
infer
वापरून रिकर्सिव्ह टाइप परिभाषित करताना काळजी घ्या, कारण ते चक्रीय अवलंबित्व आणि संकलन त्रुटींना कारणीभूत ठरू शकतात. - अत्यंत क्लिष्ट टाइप्स: अत्यंत क्लिष्ट कंडिशनल टाइप्स तयार करणे टाळा जे समजण्यास आणि सांभाळण्यास कठीण असतात. त्यांना लहान, अधिक व्यवस्थापनीय टाइप्समध्ये विभाजित करा.
infer
चे पर्याय
infer
हे एक शक्तिशाली साधन असले तरी, अशा काही परिस्थिती आहेत जिथे पर्यायी दृष्टिकोन अधिक योग्य असू शकतात:
- टाइप असर्शन्स: काही प्रकरणांमध्ये, तुम्ही एखाद्या व्हॅल्यूचा टाइप अनुमानित करण्याऐवजी स्पष्टपणे निर्दिष्ट करण्यासाठी टाइप असर्शन्स वापरू शकता. तथापि, टाइप असर्शन्स वापरताना सावधगिरी बाळगा, कारण ते टाइप तपासणीला बगल देऊ शकतात.
- टाइप गार्ड्स: रनटाइम तपासणीच्या आधारावर एखाद्या व्हॅल्यूचा टाइप मर्यादित करण्यासाठी टाइप गार्ड्स वापरले जाऊ शकतात. जेव्हा तुम्हाला रनटाइम अटींच्या आधारावर भिन्न टाइप हाताळण्याची आवश्यकता असते तेव्हा हे उपयुक्त असते.
- युटिलिटी टाइप्स: टाइपस्क्रिप्ट अनेक उपयुक्त युटिलिटी टाइप्स प्रदान करते जे सानुकूल
infer
स्टेटमेंट्सची गरज न भासता अनेक सामान्य टाइप हाताळणीची कार्ये करू शकतात.
निष्कर्ष
टाइपस्क्रिप्टमधील infer
कीवर्ड, जेव्हा कंडिशनल टाइप्ससोबत जोडला जातो, तेव्हा प्रगत टाइप हाताळणी क्षमता अनलॉक करतो. हे तुम्हाला क्लिष्ट टाइप स्ट्रक्चर्समधून विशिष्ट टाइप काढण्याची परवानगी देते, ज्यामुळे तुम्ही अधिक मजबूत, सांभाळण्यास सोपा आणि टाइप-सुरक्षित कोड लिहू शकता. फंक्शन रिटर्न टाइप अनुमानित करण्यापासून ते ऑब्जेक्ट टाइपमधून प्रॉपर्टीज काढण्यापर्यंत, शक्यता अफाट आहेत. या मार्गदर्शिकेत वर्णन केलेली तत्त्वे आणि सर्वोत्तम पद्धती समजून घेऊन, तुम्ही infer
चा पुरेपूर फायदा घेऊ शकता आणि तुमचे टाइपस्क्रिप्ट कौशल्य वाढवू शकता. तुमचे टाइप्स दस्तऐवजीकरण करणे, त्यांची कसून चाचणी करणे आणि योग्य असेल तेव्हा पर्यायी दृष्टिकोनांचा विचार करणे लक्षात ठेवा. infer
वर प्रभुत्व मिळवणे तुम्हाला खरोखरच प्रभावी आणि शक्तिशाली टाइपस्क्रिप्ट कोड लिहिण्यास सक्षम करते, ज्यामुळे शेवटी उत्तम सॉफ्टवेअर तयार होते.