டைப்ஸ்கிரிப்ட்டின் மேப்டு மற்றும் நிபந்தனை வகைகளுக்கான விரிவான வழிகாட்டி. வலுவான, வகை-பாதுகாப்பான பயன்பாடுகளை உருவாக்க நடைமுறை எடுத்துக்காட்டுகளுடன்.
டைப்ஸ்கிரிப்ட்டின் மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளில் தேர்ச்சி பெறுதல்
டைப்ஸ்கிரிப்ட், ஜாவாஸ்கிரிப்ட்டின் ஒரு சூப்பர்செட், வலுவான மற்றும் பராமரிக்கக்கூடிய பயன்பாடுகளை உருவாக்க சக்திவாய்ந்த அம்சங்களை வழங்குகிறது. இந்த அம்சங்களில், மேப்டு வகைகள் (Mapped Types) மற்றும் நிபந்தனை வகைகள் (Conditional Types) மேம்பட்ட வகை கையாளுதலுக்கான அத்தியாவசிய கருவிகளாக தனித்து நிற்கின்றன. இந்த வழிகாட்டி இந்த கருத்துகளின் விரிவான கண்ணோட்டத்தை வழங்குகிறது, அவற்றின் தொடரியல், நடைமுறை பயன்பாடுகள் மற்றும் மேம்பட்ட பயன்பாட்டு நிகழ்வுகளை ஆராய்கிறது. நீங்கள் ஒரு அனுபவம் வாய்ந்த டைப்ஸ்கிரிப்ட் டெவலப்பராக இருந்தாலும் அல்லது உங்கள் பயணத்தைத் தொடங்கினாலும், இந்த அம்சங்களை திறம்படப் பயன்படுத்த தேவையான அறிவை இந்தக் கட்டுரை உங்களுக்கு வழங்கும்.
மேப்டு வகைகள் என்றால் என்ன?
மேப்டு வகைகள், ஏற்கனவே உள்ள வகைகளை மாற்றுவதன் மூலம் புதிய வகைகளை உருவாக்க உங்களை அனுமதிக்கின்றன. அவை ஒரு தற்போதைய வகையின் பண்புகளின் மீது செயல்பட்டு, ஒவ்வொரு பண்பிற்கும் ஒரு மாற்றத்தைப் பயன்படுத்துகின்றன. அனைத்து பண்புகளையும் விருப்பமானதாக (optional) அல்லது படிக்க மட்டுமேயானதாக (read-only) மாற்றுவது போன்ற, தற்போதைய வகைகளின் மாறுபாடுகளை உருவாக்குவதற்கு இது மிகவும் பயனுள்ளதாக இருக்கும்.
அடிப்படை தொடரியல்
ஒரு மேப்டு வகையின் தொடரியல் பின்வருமாறு:
type NewType<T> = {
[K in keyof T]: Transformation;
};
T
: நீங்கள் மேப் செய்ய விரும்பும் உள்ளீட்டு வகை.K in keyof T
: உள்ளீட்டு வகைT
-யில் உள்ள ஒவ்வொரு விசைக்கும் (key) இது செயல்படும்.keyof T
என்பதுT
-யில் உள்ள அனைத்து பண்பு பெயர்களின் ஒரு யூனியனை உருவாக்குகிறது, மற்றும்K
என்பது செயல்பாட்டின் போது ஒவ்வொரு தனிப்பட்ட விசையையும் குறிக்கிறது.Transformation
: நீங்கள் ஒவ்வொரு பண்பிற்கும் பயன்படுத்த விரும்பும் மாற்றம். இது ஒரு மாற்றியமைப்பை (modifier) சேர்ப்பதாக இருக்கலாம் (readonly
அல்லது?
போன்றவை), வகையை மாற்றுவதாக இருக்கலாம், அல்லது முற்றிலும் வேறொன்றாக இருக்கலாம்.
நடைமுறை எடுத்துக்காட்டுகள்
பண்புகளை படிக்க மட்டுமேயானதாக மாற்றுதல்
ஒரு பயனர் சுயவிவரத்தைக் குறிக்கும் ஒரு இடைமுகம் உங்களிடம் இருப்பதாகக் கொள்வோம்:
interface UserProfile {
name: string;
age: number;
email: string;
}
அனைத்து பண்புகளும் படிக்க மட்டுமேயானதாக இருக்கும் ஒரு புதிய வகையை நீங்கள் உருவாக்கலாம்:
type ReadOnlyUserProfile = {
readonly [K in keyof UserProfile]: UserProfile[K];
};
இப்போது, ReadOnlyUserProfile
ஆனது UserProfile
போன்ற அதே பண்புகளைக் கொண்டிருக்கும், ஆனால் அவை அனைத்தும் படிக்க மட்டுமேயானதாக இருக்கும்.
பண்புகளை விருப்பமானதாக மாற்றுதல்
இதேபோல், நீங்கள் அனைத்து பண்புகளையும் விருப்பமானதாக மாற்றலாம்:
type OptionalUserProfile = {
[K in keyof UserProfile]?: UserProfile[K];
};
OptionalUserProfile
ஆனது UserProfile
-இன் அனைத்து பண்புகளையும் கொண்டிருக்கும், ஆனால் ஒவ்வொரு பண்பும் விருப்பமானதாக இருக்கும்.
பண்பு வகைகளை மாற்றுதல்
நீங்கள் ஒவ்வொரு பண்பின் வகையையும் மாற்றலாம். எடுத்துக்காட்டாக, நீங்கள் அனைத்து பண்புகளையும் ஸ்டிரிங்குகளாக மாற்றலாம்:
type StringifiedUserProfile = {
[K in keyof UserProfile]: string;
};
இந்த வழக்கில், StringifiedUserProfile
-இல் உள்ள அனைத்து பண்புகளும் string
வகையாக இருக்கும்.
நிபந்தனை வகைகள் என்றால் என்ன?
நிபந்தனை வகைகள், ஒரு நிபந்தனையைப் பொறுத்து அமையும் வகைகளை வரையறுக்க உங்களை அனுமதிக்கின்றன. ஒரு வகை ஒரு குறிப்பிட்ட கட்டுப்பாட்டை திருப்திப்படுத்துகிறதா என்பதைப் பொறுத்து வகை உறவுகளை வெளிப்படுத்த அவை ஒரு வழியை வழங்குகின்றன. இது ஜாவாஸ்கிரிப்டில் உள்ள ஒரு டெர்னரி ஆபரேட்டரைப் போன்றது, ஆனால் இது வகைகளுக்கானது.
அடிப்படை தொடரியல்
ஒரு நிபந்தனை வகையின் தொடரியல் பின்வருமாறு:
T extends U ? X : Y
T
: சரிபார்க்கப்படும் வகை.U
:T
ஆல் நீட்டிக்கப்படும் வகை (நிபந்தனை).X
:T
ஆனதுU
-ஐ நீட்டித்தால் (நிபந்தனை உண்மையாக இருந்தால்) திரும்பப் பெறப்படும் வகை.Y
:T
ஆனதுU
-ஐ நீட்டிக்கவில்லை என்றால் (நிபந்தனை பொய்யாக இருந்தால்) திரும்பப் பெறப்படும் வகை.
நடைமுறை எடுத்துக்காட்டுகள்
ஒரு வகை ஸ்டிரிங் தானா என்பதைத் தீர்மானித்தல்
உள்ளீட்டு வகை ஸ்டிரிங்காக இருந்தால் 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
ஒரு யூனியனிலிருந்து வகையைப் பிரித்தெடுத்தல்
ஒரு யூனியன் வகையிலிருந்து ஒரு குறிப்பிட்ட வகையைப் பிரித்தெடுக்க நீங்கள் நிபந்தனை வகைகளைப் பயன்படுத்தலாம். எடுத்துக்காட்டாக, null அல்லாத வகைகளைப் பிரித்தெடுக்க:
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
ஒரு செயல்பாட்டின் திரும்பும் வகையை (return type) பிரித்தெடுக்கிறது. இது T
என்பது எந்தவொரு தருமதிப்புகளையும் (arguments) எடுத்து R
என்ற வகையைத் திருப்பும் ஒரு செயல்பாடா என்று சரிபார்க்கிறது. அப்படியானால், அது R
-ஐத் திருப்புகிறது; இல்லையெனில், அது any
-ஐத் திருப்புகிறது.
மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளை இணைத்தல்
மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளின் உண்மையான சக்தி அவற்றை இணைப்பதில் இருந்து வருகிறது. இது மிகவும் நெகிழ்வான மற்றும் வெளிப்படையான வகை மாற்றங்களை உருவாக்க உங்களை அனுமதிக்கிறது.
எடுத்துக்காட்டு: ஆழமான படிக்க மட்டுமே (Deep Readonly)
ஒரு பொதுவான பயன்பாட்டு நிகழ்வு, ஒரு பொருளின் அனைத்து பண்புகளையும், உட்பொதிந்த பண்புகளையும் சேர்த்து, படிக்க மட்டுமேயானதாக மாற்றும் ஒரு வகையை உருவாக்குவதாகும். இது ஒரு சுழல்நிலை (recursive) நிபந்தனை வகையைப் பயன்படுத்தி அடையப்படலாம்.
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
-ஐ நீட்டிக்கிறதா என்று சரிபார்க்கிறது. அவ்வாறு செய்தால், அது அந்த பண்பை விளைவு வகையில் சேர்க்கிறது; இல்லையெனில், விசையை never
என்று மேப் செய்வதன் மூலம் அதை விலக்குகிறது. விசைகளை மீண்டும் மேப் செய்ய "as" பயன்படுத்தப்படுவதைக் கவனியுங்கள். பின்னர், அசல் இடைமுகத்திலிருந்து ஸ்டிரிங் பண்புகளை அகற்ற `Omit` மற்றும் `keyof StringProperties`-ஐப் பயன்படுத்துகிறோம்.
மேம்பட்ட பயன்பாட்டு நிகழ்வுகள் மற்றும் வடிவங்கள்
அடிப்படை எடுத்துக்காட்டுகளுக்கு அப்பால், மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகள் மிகவும் தனிப்பயனாக்கக்கூடிய மற்றும் வகை-பாதுகாப்பான பயன்பாடுகளை உருவாக்க மேம்பட்ட சூழ்நிலைகளில் பயன்படுத்தப்படலாம்.
பகிர்ந்தளிக்கப்படும் நிபந்தனை வகைகள் (Distributive Conditional Types)
சரிபார்க்கப்படும் வகை ஒரு யூனியன் வகையாக இருக்கும்போது நிபந்தனை வகைகள் பகிர்ந்தளிக்கப்படுகின்றன. இதன் பொருள், நிபந்தனை யூனியனின் ஒவ்வொரு உறுப்பினருக்கும் தனித்தனியாகப் பயன்படுத்தப்படுகிறது, பின்னர் முடிவுகள் ஒரு புதிய யூனியன் வகையாக இணைக்கப்படுகின்றன.
type ToArray<T> = T extends any ? T[] : never;
type Result6 = ToArray<string | number>; // string[] | number[]
இந்த எடுத்துக்காட்டில், ToArray
என்பது string | number
என்ற யூனியனின் ஒவ்வொரு உறுப்பினருக்கும் தனித்தனியாகப் பயன்படுத்தப்படுகிறது, இதன் விளைவாக string[] | number[]
கிடைக்கிறது. நிபந்தனை பகிர்ந்தளிக்கப்படாவிட்டால், இதன் விளைவு (string | number)[]
ஆக இருந்திருக்கும்.
பயன்பாட்டு வகைகளைப் பயன்படுத்துதல்
டைப்ஸ்கிரிப்ட் மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளைப் பயன்படுத்தும் பல உள்ளமைக்கப்பட்ட பயன்பாட்டு வகைகளை வழங்குகிறது. இந்த பயன்பாட்டு வகைகளை மிகவும் சிக்கலான வகை மாற்றங்களுக்கான கட்டுமானத் தொகுதிகளாகப் பயன்படுத்தலாம்.
Partial<T>
:T
-யின் அனைத்து பண்புகளையும் விருப்பமானதாக மாற்றுகிறது.Required<T>
:T
-யின் அனைத்து பண்புகளையும் அவசியமானதாக மாற்றுகிறது.Readonly<T>
:T
-யின் அனைத்து பண்புகளையும் படிக்க மட்டுமேயானதாக மாற்றுகிறது.Pick<T, K>
:T
-யிலிருந்துK
என்ற பண்புகளின் தொகுப்பைத் தேர்ந்தெடுக்கிறது.Omit<T, K>
:T
-யிலிருந்துK
என்ற பண்புகளின் தொகுப்பை நீக்குகிறது.Record<K, T>
:T
வகையின்K
பண்புகளின் தொகுப்புடன் ஒரு வகையை உருவாக்குகிறது.Exclude<T, U>
:T
-யிலிருந்துU
-க்கு ஒதுக்கக்கூடிய அனைத்து வகைகளையும் விலக்குகிறது.Extract<T, U>
:T
-யிலிருந்துU
-க்கு ஒதுக்கக்கூடிய அனைத்து வகைகளையும் பிரித்தெடுக்கிறது.NonNullable<T>
:T
-யிலிருந்துnull
மற்றும்undefined
-ஐ விலக்குகிறது.Parameters<T>
: ஒரு செயல்பாட்டு வகைT
-யின் அளவுருக்களைப் பெறுகிறது.ReturnType<T>
: ஒரு செயல்பாட்டு வகைT
-யின் திரும்பும் வகையைப் பெறுகிறது.InstanceType<T>
: ஒரு கட்டமைப்பான் செயல்பாட்டு வகைT
-யின் நிகழ்வு வகையைப் பெறுகிறது.
இந்த பயன்பாட்டு வகைகள் சிக்கலான வகை கையாளுதல்களை எளிதாக்கக்கூடிய சக்திவாய்ந்த கருவிகளாகும். எடுத்துக்காட்டாக, குறிப்பிட்ட பண்புகளை மட்டும் விருப்பமானதாக மாற்ற நீங்கள் 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
பண்பு விருப்பமானது.
டெம்ப்ளேட் லிட்டரல் வகைகளைப் பயன்படுத்துதல்
டெம்ப்ளேட் லிட்டரல் வகைகள், ஸ்டிரிங் லிட்டரல்களின் அடிப்படையில் வகைகளை உருவாக்க உங்களை அனுமதிக்கின்றன. அவற்றை மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளுடன் இணைந்து மாறும் மற்றும் வெளிப்படையான வகை மாற்றங்களை உருவாக்கப் பயன்படுத்தலாம். எடுத்துக்காட்டாக, அனைத்து பண்பு பெயர்களுக்கும் ஒரு குறிப்பிட்ட ஸ்டிரிங்கை முன்னொட்டாகச் சேர்க்கும் ஒரு வகையை நீங்கள் உருவாக்கலாம்:
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
என்ற பண்புகளைக் கொண்டிருக்கும்.
சிறந்த நடைமுறைகள் மற்றும் பரிசீலனைகள்
- எளிமையாக வைத்திருங்கள்: மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகள் சக்திவாய்ந்தவை என்றாலும், அவை உங்கள் குறியீட்டை மேலும் சிக்கலாக்கக்கூடும். உங்கள் வகை மாற்றங்களை முடிந்தவரை எளிமையாக வைத்திருக்க முயற்சி செய்யுங்கள்.
- பயன்பாட்டு வகைகளைப் பயன்படுத்துங்கள்: முடிந்தவரை டைப்ஸ்கிரிப்ட்டின் உள்ளமைக்கப்பட்ட பயன்பாட்டு வகைகளைப் பயன்படுத்துங்கள். அவை நன்கு சோதிக்கப்பட்டவை மற்றும் உங்கள் குறியீட்டை எளிதாக்கக்கூடும்.
- உங்கள் வகைகளை ஆவணப்படுத்துங்கள்: உங்கள் வகை மாற்றங்களை தெளிவாக ஆவணப்படுத்துங்கள், குறிப்பாக அவை சிக்கலானதாக இருந்தால். இது மற்ற டெவலப்பர்கள் உங்கள் குறியீட்டைப் புரிந்துகொள்ள உதவும்.
- உங்கள் வகைகளை சோதிக்கவும்: உங்கள் வகை மாற்றங்கள் எதிர்பார்த்தபடி செயல்படுகின்றனவா என்பதை உறுதிப்படுத்த டைப்ஸ்கிரிப்ட்டின் வகை சரிபார்ப்பைப் பயன்படுத்தவும். உங்கள் வகைகளின் நடத்தையைச் சரிபார்க்க நீங்கள் யூனிட் சோதனைகளை எழுதலாம்.
- செயல்திறனைக் கவனியுங்கள்: சிக்கலான வகை மாற்றங்கள் உங்கள் டைப்ஸ்கிரிப்ட் கம்பைலரின் செயல்திறனைப் பாதிக்கலாம். உங்கள் வகைகளின் சிக்கலான தன்மையைக் கருத்தில் கொண்டு தேவையற்ற கணக்கீடுகளைத் தவிர்க்கவும்.
முடிவுரை
மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகள் டைப்ஸ்கிரிப்டில் மிகவும் நெகிழ்வான மற்றும் வெளிப்படையான வகை மாற்றங்களை உருவாக்க உதவும் சக்திவாய்ந்த அம்சங்கள். இந்த கருத்துகளில் தேர்ச்சி பெறுவதன் மூலம், உங்கள் டைப்ஸ்கிரிப்ட் பயன்பாடுகளின் வகை பாதுகாப்பு, பராமரிப்பு மற்றும் ஒட்டுமொத்த தரத்தை மேம்படுத்தலாம். பண்புகளை விருப்பமானதாக அல்லது படிக்க மட்டுமேயானதாக மாற்றுவது போன்ற எளிய மாற்றங்கள் முதல் சிக்கலான சுழல்நிலை மாற்றங்கள் மற்றும் நிபந்தனை தர்க்கம் வரை, இந்த அம்சங்கள் வலுவான மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்கத் தேவையான கருவிகளை வழங்குகின்றன. இந்த அம்சங்களின் முழு திறனையும் திறக்க மற்றும் மேலும் திறமையான டைப்ஸ்கிரிப்ட் டெவலப்பராக மாற தொடர்ந்து ஆராய்ந்து பரிசோதனை செய்யுங்கள்.
உங்கள் டைப்ஸ்கிரிப்ட் பயணத்தைத் தொடரும்போது, அதிகாரப்பூர்வ டைப்ஸ்கிரிப்ட் ஆவணங்கள், ஆன்லைன் சமூகங்கள் மற்றும் திறந்த மூல திட்டங்கள் உட்பட கிடைக்கக்கூடிய வளங்களின் செல்வத்தைப் பயன்படுத்த நினைவில் கொள்ளுங்கள். மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளின் சக்தியைத் தழுவுங்கள், மேலும் சவாலான வகை தொடர்பான சிக்கல்களைக் கூட சமாளிக்க நீங்கள் நன்கு தயாராக இருப்பீர்கள்.