मराठी

टाइपस्क्रिप्ट '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 हे एक शक्तिशाली साधन असले तरी, अशा काही परिस्थिती आहेत जिथे पर्यायी दृष्टिकोन अधिक योग्य असू शकतात:

निष्कर्ष

टाइपस्क्रिप्टमधील infer कीवर्ड, जेव्हा कंडिशनल टाइप्ससोबत जोडला जातो, तेव्हा प्रगत टाइप हाताळणी क्षमता अनलॉक करतो. हे तुम्हाला क्लिष्ट टाइप स्ट्रक्चर्समधून विशिष्ट टाइप काढण्याची परवानगी देते, ज्यामुळे तुम्ही अधिक मजबूत, सांभाळण्यास सोपा आणि टाइप-सुरक्षित कोड लिहू शकता. फंक्शन रिटर्न टाइप अनुमानित करण्यापासून ते ऑब्जेक्ट टाइपमधून प्रॉपर्टीज काढण्यापर्यंत, शक्यता अफाट आहेत. या मार्गदर्शिकेत वर्णन केलेली तत्त्वे आणि सर्वोत्तम पद्धती समजून घेऊन, तुम्ही infer चा पुरेपूर फायदा घेऊ शकता आणि तुमचे टाइपस्क्रिप्ट कौशल्य वाढवू शकता. तुमचे टाइप्स दस्तऐवजीकरण करणे, त्यांची कसून चाचणी करणे आणि योग्य असेल तेव्हा पर्यायी दृष्टिकोनांचा विचार करणे लक्षात ठेवा. infer वर प्रभुत्व मिळवणे तुम्हाला खरोखरच प्रभावी आणि शक्तिशाली टाइपस्क्रिप्ट कोड लिहिण्यास सक्षम करते, ज्यामुळे शेवटी उत्तम सॉफ्टवेअर तयार होते.