हिन्दी

टाइपस्क्रिप्ट '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 एक शक्तिशाली उपकरण है, ऐसी स्थितियाँ हैं जहाँ वैकल्पिक दृष्टिकोण अधिक उपयुक्त हो सकते हैं:

निष्कर्ष

टाइपस्क्रिप्ट में infer कीवर्ड, जब सशर्त प्रकारों के साथ जोड़ा जाता है, तो उन्नत प्रकार हेरफेर क्षमताओं को अनलॉक करता है। यह आपको जटिल प्रकार संरचनाओं से विशिष्ट प्रकारों को निकालने की अनुमति देता है, जिससे आप अधिक मजबूत, बनाए रखने योग्य और प्रकार-सुरक्षित कोड लिख सकते हैं। फ़ंक्शन रिटर्न प्रकारों का अनुमान लगाने से लेकर ऑब्जेक्ट प्रकारों से गुणों को निकालने तक, संभावनाएँ विशाल हैं। इस गाइड में बताए गए सिद्धांतों और सर्वोत्तम प्रथाओं को समझकर, आप infer का पूरी क्षमता से लाभ उठा सकते हैं और अपने टाइपस्क्रिप्ट कौशल को बढ़ा सकते हैं। अपने प्रकारों का दस्तावेजीकरण करना, उनका अच्छी तरह से परीक्षण करना और उपयुक्त होने पर वैकल्पिक दृष्टिकोणों पर विचार करना याद रखें। infer में महारत हासिल करने से आप वास्तव में अभिव्यंजक और शक्तिशाली टाइपस्क्रिप्ट कोड लिख सकते हैं, जिसके परिणामस्वरूप अंततः बेहतर सॉफ़्टवेयर बनता है।