मराठी

टाइपस्क्रिप्टच्या शक्तिशाली मॅप्ड टाइप्स आणि कंडिशनल टाइप्ससाठी एक सर्वसमावेशक मार्गदर्शक, मजबूत आणि टाइप-सेफ ॲप्लिकेशन्स तयार करण्यासाठी व्यावहारिक उदाहरणे आणि प्रगत उपयोगांसह.

टाइपस्क्रिप्टच्या मॅप्ड टाइप्स आणि कंडिशनल टाइप्समध्ये प्राविण्य मिळवणे

टाइपस्क्रिप्ट, जी जावास्क्रिप्टची एक सुपरसेट आहे, मजबूत आणि सुस्थितीत ठेवता येण्याजोगे ॲप्लिकेशन्स तयार करण्यासाठी शक्तिशाली वैशिष्ट्ये प्रदान करते. या वैशिष्ट्यांमध्ये, मॅप्ड टाइप्स (Mapped Types) आणि कंडिशनल टाइप्स (Conditional Types) प्रगत टाइप मॅनिप्युलेशनसाठी आवश्यक साधने म्हणून ओळखली जातात. हा मार्गदर्शक या संकल्पनांचा सर्वसमावेशक आढावा देतो, ज्यात त्यांचे सिंटॅक्स, व्यावहारिक उपयोग आणि प्रगत वापर प्रकरणे शोधली आहेत. तुम्ही अनुभवी टाइपस्क्रिप्ट डेव्हलपर असाल किंवा नुकतीच सुरुवात करत असाल, हा लेख तुम्हाला या वैशिष्ट्यांचा प्रभावीपणे वापर करण्यासाठी आवश्यक ज्ञान देईल.

मॅप्ड टाइप्स म्हणजे काय?

मॅप्ड टाइप्स तुम्हाला विद्यमान टाइप्सना रूपांतरित करून नवीन टाइप्स तयार करण्याची परवानगी देतात. ते विद्यमान टाइपच्या प्रॉपर्टीजवर पुनरावृत्ती करतात आणि प्रत्येक प्रॉपर्टीवर एक परिवर्तन लागू करतात. हे विद्यमान टाइप्सचे व्हेरिएशन तयार करण्यासाठी विशेषतः उपयुक्त आहे, जसे की सर्व प्रॉपर्टीजना ऐच्छिक (optional) किंवा फक्त-वाचनीय (read-only) बनवणे.

मूलभूत सिंटॅक्स

मॅप्ड टाइपसाठी सिंटॅक्स खालीलप्रमाणे आहे:

type NewType<T> = {
  [K in keyof T]: Transformation;
};

व्यावहारिक उदाहरणे

प्रॉपर्टीजना फक्त-वाचनीय (Read-Only) बनवणे

समजा तुमच्याकडे एक इंटरफेस आहे जो युझर प्रोफाइल दर्शवतो:

interface UserProfile {
  name: string;
  age: number;
  email: string;
}

तुम्ही एक नवीन टाइप तयार करू शकता जिथे सर्व प्रॉपर्टीज फक्त-वाचनीय (read-only) असतील:

type ReadOnlyUserProfile = {
  readonly [K in keyof UserProfile]: UserProfile[K];
};

आता, ReadOnlyUserProfile मध्ये UserProfile सारख्याच प्रॉपर्टीज असतील, पण त्या सर्व फक्त-वाचनीय असतील.

प्रॉपर्टीजना ऐच्छिक (Optional) बनवणे

त्याचप्रमाणे, तुम्ही सर्व प्रॉपर्टीजना ऐच्छिक बनवू शकता:

type OptionalUserProfile = {
  [K in keyof UserProfile]?: UserProfile[K];
};

OptionalUserProfile मध्ये UserProfile च्या सर्व प्रॉपर्टीज असतील, पण प्रत्येक प्रॉपर्टी ऐच्छिक असेल.

प्रॉपर्टी टाइप्समध्ये बदल करणे

तुम्ही प्रत्येक प्रॉपर्टीचा टाइप देखील बदलू शकता. उदाहरणार्थ, तुम्ही सर्व प्रॉपर्टीजना स्ट्रिंगमध्ये रूपांतरित करू शकता:

type StringifiedUserProfile = {
  [K in keyof UserProfile]: string;
};

या प्रकरणात, StringifiedUserProfile मधील सर्व प्रॉपर्टीज string टाइपच्या असतील.

कंडिशनल टाइप्स म्हणजे काय?

कंडिशनल टाइप्स तुम्हाला अशा टाइप्सची व्याख्या करण्याची परवानगी देतात जे एका अटीवर अवलंबून असतात. ते एका टाइपने विशिष्ट अट पूर्ण केली आहे की नाही यावर आधारित टाइप संबंध व्यक्त करण्याचा एक मार्ग प्रदान करतात. हे जावास्क्रिप्टमधील टर्नरी ऑपरेटरसारखेच आहे, पण टाइप्ससाठी.

मूलभूत सिंटॅक्स

कंडिशनल टाइपसाठी सिंटॅक्स खालीलप्रमाणे आहे:

T extends U ? X : Y

व्यावहारिक उदाहरणे

एखादा टाइप स्ट्रिंग आहे की नाही हे ठरवणे

चला एक असा टाइप तयार करूया जो इनपुट टाइप स्ट्रिंग असल्यास string परत करतो, अन्यथा number परत करतो:

type StringOrNumber<T> = T extends string ? string : number;

type Result1 = StringOrNumber<string>;  // string
type Result2 = StringOrNumber<number>;  // number
type Result3 = StringOrNumber<boolean>; // number

युनियनमधून टाइप काढणे

तुम्ही युनियन टाइपमधून विशिष्ट टाइप काढण्यासाठी कंडिशनल टाइप्स वापरू शकता. उदाहरणार्थ, नॉन-नलेबल (non-nullable) टाइप्स काढण्यासाठी:

type NonNullable<T> = T extends null | undefined ? never : T;

type Result4 = NonNullable<string | null | undefined>; // string

येथे, जर T हे null किंवा undefined असेल, तर टाइप never होतो, जो नंतर टाइपस्क्रिप्टच्या युनियन टाइप सरलीकरणाद्वारे फिल्टर केला जातो.

टाइप्सचे अनुमान लावणे (Inferring Types)

कंडिशनल टाइप्स infer कीवर्ड वापरून टाइप्सचे अनुमान लावण्यासाठी देखील वापरले जाऊ शकतात. हे तुम्हाला अधिक जटिल टाइप स्ट्रक्चरमधून टाइप काढण्याची परवानगी देते.

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

function myFunction(x: number): string {
  return x.toString();
}

type Result5 = ReturnType<typeof myFunction>; // string

या उदाहरणात, ReturnType फंक्शनचा रिटर्न टाइप काढतो. ते तपासते की T एक फंक्शन आहे का जे कोणतेही आर्ग्युमेंट्स घेते आणि R टाइप परत करते. जर हो, तर ते R परत करते; अन्यथा, ते any परत करते.

मॅप्ड टाइप्स आणि कंडिशनल टाइप्स एकत्र करणे

मॅप्ड टाइप्स आणि कंडिशनल टाइप्सची खरी शक्ती त्यांना एकत्र वापरण्यात आहे. हे तुम्हाला अत्यंत लवचिक आणि अर्थपूर्ण टाइप परिवर्तने तयार करण्याची परवानगी देते.

उदाहरण: डीप रीडओन्ली (Deep Readonly)

एक सामान्य वापर म्हणजे असा टाइप तयार करणे जो ऑब्जेक्टच्या सर्व प्रॉपर्टीजना, नेस्टेड प्रॉपर्टीजसह, फक्त-वाचनीय बनवतो. हे रिकर्सिव्ह कंडिशनल टाइप वापरून साध्य केले जाऊ शकते.

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};

interface Company {
  name: string;
  address: {
    street: string;
    city: string;
  };
}

type ReadonlyCompany = DeepReadonly<Company>;

येथे, DeepReadonly रिकर्सिव्हपणे readonly मॉडिफायर सर्व प्रॉपर्टीज आणि त्यांच्या नेस्टेड प्रॉपर्टीजवर लागू करते. जर एखादी प्रॉपर्टी ऑब्जेक्ट असेल, तर ते त्या ऑब्जेक्टवर DeepReadonly रिकर्सिव्हपणे कॉल करते. अन्यथा, ते फक्त प्रॉपर्टीवर readonly मॉडिफायर लागू करते.

उदाहरण: टाइपनुसार प्रॉपर्टीज फिल्टर करणे

समजा तुम्हाला असा टाइप तयार करायचा आहे ज्यात फक्त विशिष्ट टाइपच्या प्रॉपर्टीज समाविष्ट असतील. हे साध्य करण्यासाठी तुम्ही मॅप्ड टाइप्स आणि कंडिशनल टाइप्स एकत्र करू शकता.

type FilterByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

interface Person {
  name: string;
  age: number;
  isEmployed: boolean;
}

type StringProperties = FilterByType<Person, string>; // { name: string; }

type NonStringProperties = Omit<Person, keyof StringProperties>;

या उदाहरणात, FilterByType हे T च्या प्रॉपर्टीजवर पुनरावृत्ती करते आणि प्रत्येक प्रॉपर्टीचा टाइप U ला विस्तारतो की नाही हे तपासते. जर तो विस्तारत असेल, तर ती प्रॉपर्टी परिणामी टाइपमध्ये समाविष्ट करते; अन्यथा, की (key) ला never वर मॅप करून ती वगळते. की (keys) पुन्हा मॅप करण्यासाठी "as" चा वापर लक्षात घ्या. त्यानंतर आम्ही मूळ इंटरफेसमधून स्ट्रिंग प्रॉपर्टीज काढण्यासाठी `Omit` आणि `keyof StringProperties` वापरतो.

प्रगत वापर आणि पॅटर्न्स

मूलभूत उदाहरणांपलीकडे, मॅप्ड टाइप्स आणि कंडिशनल टाइप्स अधिक प्रगत परिस्थितीत अत्यंत सानुकूल आणि टाइप-सेफ ॲप्लिकेशन्स तयार करण्यासाठी वापरले जाऊ शकतात.

डिस्ट्रिब्युटिव्ह कंडिशनल टाइप्स

जेव्हा तपासला जाणारा टाइप युनियन टाइप असतो, तेव्हा कंडिशनल टाइप्स डिस्ट्रिब्युटिव्ह असतात. याचा अर्थ असा की अट युनियनच्या प्रत्येक सदस्यावर स्वतंत्रपणे लागू केली जाते, आणि परिणाम नंतर नवीन युनियन टाइपमध्ये एकत्र केले जातात.

type ToArray<T> = T extends any ? T[] : never;

type Result6 = ToArray<string | number>; // string[] | number[]

या उदाहरणात, ToArray हे युनियन string | number च्या प्रत्येक सदस्यावर स्वतंत्रपणे लागू केले जाते, ज्यामुळे string[] | number[] परिणाम मिळतो. जर अट डिस्ट्रिब्युटिव्ह नसती, तर परिणाम (string | number)[] असता.

युटिलिटी टाइप्सचा वापर

टाइपस्क्रिप्ट अनेक अंगभूत युटिलिटी टाइप्स प्रदान करते जे मॅप्ड टाइप्स आणि कंडिशनल टाइप्सचा फायदा घेतात. हे युटिलिटी टाइप्स अधिक जटिल टाइप परिवर्तनांसाठी बिल्डिंग ब्लॉक्स म्हणून वापरले जाऊ शकतात.

हे युटिलिटी टाइप्स शक्तिशाली साधने आहेत जी जटिल टाइप मॅनिप्युलेशन्स सोपे करू शकतात. उदाहरणार्थ, तुम्ही Pick आणि Partial एकत्र करून असा टाइप तयार करू शकता जो फक्त काही विशिष्ट प्रॉपर्टीजना ऐच्छिक बनवतो:

type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

interface Product {
  id: number;
  name: string;
  price: number;
  description: string;
}

type OptionalDescriptionProduct = Optional<Product, "description">;

या उदाहरणात, OptionalDescriptionProduct मध्ये Product च्या सर्व प्रॉपर्टीज आहेत, पण description प्रॉपर्टी ऐच्छिक आहे.

टेम्पलेट लिटरल टाइप्सचा वापर

टेम्पलेट लिटरल टाइप्स तुम्हाला स्ट्रिंग लिटरलवर आधारित टाइप्स तयार करण्याची परवानगी देतात. ते मॅप्ड टाइप्स आणि कंडिशनल टाइप्ससह एकत्र वापरून डायनॅमिक आणि अर्थपूर्ण टाइप परिवर्तने तयार केली जाऊ शकतात. उदाहरणार्थ, तुम्ही असा टाइप तयार करू शकता जो सर्व प्रॉपर्टी नावांना एका विशिष्ट स्ट्रिंगसह préfix करतो:

type Prefix<T, P extends string> = {
  [K in keyof T as `${P}${string & K}`]: T[K];
};

interface Settings {
  apiUrl: string;
  timeout: number;
}

type PrefixedSettings = Prefix<Settings, "data_">;

या उदाहरणात, PrefixedSettings मध्ये data_apiUrl आणि data_timeout प्रॉपर्टीज असतील.

सर्वोत्तम पद्धती आणि विचार

निष्कर्ष

मॅप्ड टाइप्स आणि कंडिशनल टाइप्स टाइपस्क्रिप्टमधील शक्तिशाली वैशिष्ट्ये आहेत जी तुम्हाला अत्यंत लवचिक आणि अर्थपूर्ण टाइप परिवर्तने तयार करण्यास सक्षम करतात. या संकल्पनांवर प्रभुत्व मिळवून, तुम्ही तुमच्या टाइपस्क्रिप्ट ॲप्लिकेशन्सची टाइप सेफ्टी, देखभालक्षमता आणि एकूण गुणवत्ता सुधारू शकता. प्रॉपर्टीजना ऐच्छिक किंवा फक्त-वाचनीय बनवण्यासारख्या सोप्या परिवर्तनांपासून ते जटिल रिकर्सिव्ह परिवर्तने आणि कंडिशनल लॉजिकपर्यंत, ही वैशिष्ट्ये तुम्हाला मजबूत आणि स्केलेबल ॲप्लिकेशन्स तयार करण्यासाठी आवश्यक साधने प्रदान करतात. त्यांची पूर्ण क्षमता अनलॉक करण्यासाठी आणि अधिक प्रवीण टाइपस्क्रिप्ट डेव्हलपर बनण्यासाठी या वैशिष्ट्यांचे अन्वेषण आणि प्रयोग करत रहा.

तुमच्या टाइपस्क्रिप्ट प्रवासात पुढे जात असताना, अधिकृत टाइपस्क्रिप्ट दस्तऐवजीकरण, ऑनलाइन समुदाय आणि ओपन-सोर्स प्रोजेक्ट्ससह उपलब्ध असलेल्या विपुल संसाधनांचा फायदा घेण्याचे लक्षात ठेवा. मॅप्ड टाइप्स आणि कंडिशनल टाइप्सच्या सामर्थ्याचा स्वीकार करा, आणि तुम्ही सर्वात आव्हानात्मक टाइप-संबंधित समस्यांना तोंड देण्यासाठी सुसज्ज असाल.