தமிழ்

டைப்ஸ்கிரிப்ட்டின் மேப்டு மற்றும் நிபந்தனை வகைகளுக்கான விரிவான வழிகாட்டி. வலுவான, வகை-பாதுகாப்பான பயன்பாடுகளை உருவாக்க நடைமுறை எடுத்துக்காட்டுகளுடன்.

டைப்ஸ்கிரிப்ட்டின் மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளில் தேர்ச்சி பெறுதல்

டைப்ஸ்கிரிப்ட், ஜாவாஸ்கிரிப்ட்டின் ஒரு சூப்பர்செட், வலுவான மற்றும் பராமரிக்கக்கூடிய பயன்பாடுகளை உருவாக்க சக்திவாய்ந்த அம்சங்களை வழங்குகிறது. இந்த அம்சங்களில், மேப்டு வகைகள் (Mapped Types) மற்றும் நிபந்தனை வகைகள் (Conditional Types) மேம்பட்ட வகை கையாளுதலுக்கான அத்தியாவசிய கருவிகளாக தனித்து நிற்கின்றன. இந்த வழிகாட்டி இந்த கருத்துகளின் விரிவான கண்ணோட்டத்தை வழங்குகிறது, அவற்றின் தொடரியல், நடைமுறை பயன்பாடுகள் மற்றும் மேம்பட்ட பயன்பாட்டு நிகழ்வுகளை ஆராய்கிறது. நீங்கள் ஒரு அனுபவம் வாய்ந்த டைப்ஸ்கிரிப்ட் டெவலப்பராக இருந்தாலும் அல்லது உங்கள் பயணத்தைத் தொடங்கினாலும், இந்த அம்சங்களை திறம்படப் பயன்படுத்த தேவையான அறிவை இந்தக் கட்டுரை உங்களுக்கு வழங்கும்.

மேப்டு வகைகள் என்றால் என்ன?

மேப்டு வகைகள், ஏற்கனவே உள்ள வகைகளை மாற்றுவதன் மூலம் புதிய வகைகளை உருவாக்க உங்களை அனுமதிக்கின்றன. அவை ஒரு தற்போதைய வகையின் பண்புகளின் மீது செயல்பட்டு, ஒவ்வொரு பண்பிற்கும் ஒரு மாற்றத்தைப் பயன்படுத்துகின்றன. அனைத்து பண்புகளையும் விருப்பமானதாக (optional) அல்லது படிக்க மட்டுமேயானதாக (read-only) மாற்றுவது போன்ற, தற்போதைய வகைகளின் மாறுபாடுகளை உருவாக்குவதற்கு இது மிகவும் பயனுள்ளதாக இருக்கும்.

அடிப்படை தொடரியல்

ஒரு மேப்டு வகையின் தொடரியல் பின்வருமாறு:

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

நடைமுறை எடுத்துக்காட்டுகள்

பண்புகளை படிக்க மட்டுமேயானதாக மாற்றுதல்

ஒரு பயனர் சுயவிவரத்தைக் குறிக்கும் ஒரு இடைமுகம் உங்களிடம் இருப்பதாகக் கொள்வோம்:

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

நடைமுறை எடுத்துக்காட்டுகள்

ஒரு வகை ஸ்டிரிங் தானா என்பதைத் தீர்மானித்தல்

உள்ளீட்டு வகை ஸ்டிரிங்காக இருந்தால் 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)[] ஆக இருந்திருக்கும்.

பயன்பாட்டு வகைகளைப் பயன்படுத்துதல்

டைப்ஸ்கிரிப்ட் மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளைப் பயன்படுத்தும் பல உள்ளமைக்கப்பட்ட பயன்பாட்டு வகைகளை வழங்குகிறது. இந்த பயன்பாட்டு வகைகளை மிகவும் சிக்கலான வகை மாற்றங்களுக்கான கட்டுமானத் தொகுதிகளாகப் பயன்படுத்தலாம்.

இந்த பயன்பாட்டு வகைகள் சிக்கலான வகை கையாளுதல்களை எளிதாக்கக்கூடிய சக்திவாய்ந்த கருவிகளாகும். எடுத்துக்காட்டாக, குறிப்பிட்ட பண்புகளை மட்டும் விருப்பமானதாக மாற்ற நீங்கள் 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 என்ற பண்புகளைக் கொண்டிருக்கும்.

சிறந்த நடைமுறைகள் மற்றும் பரிசீலனைகள்

முடிவுரை

மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகள் டைப்ஸ்கிரிப்டில் மிகவும் நெகிழ்வான மற்றும் வெளிப்படையான வகை மாற்றங்களை உருவாக்க உதவும் சக்திவாய்ந்த அம்சங்கள். இந்த கருத்துகளில் தேர்ச்சி பெறுவதன் மூலம், உங்கள் டைப்ஸ்கிரிப்ட் பயன்பாடுகளின் வகை பாதுகாப்பு, பராமரிப்பு மற்றும் ஒட்டுமொத்த தரத்தை மேம்படுத்தலாம். பண்புகளை விருப்பமானதாக அல்லது படிக்க மட்டுமேயானதாக மாற்றுவது போன்ற எளிய மாற்றங்கள் முதல் சிக்கலான சுழல்நிலை மாற்றங்கள் மற்றும் நிபந்தனை தர்க்கம் வரை, இந்த அம்சங்கள் வலுவான மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்கத் தேவையான கருவிகளை வழங்குகின்றன. இந்த அம்சங்களின் முழு திறனையும் திறக்க மற்றும் மேலும் திறமையான டைப்ஸ்கிரிப்ட் டெவலப்பராக மாற தொடர்ந்து ஆராய்ந்து பரிசோதனை செய்யுங்கள்.

உங்கள் டைப்ஸ்கிரிப்ட் பயணத்தைத் தொடரும்போது, அதிகாரப்பூர்வ டைப்ஸ்கிரிப்ட் ஆவணங்கள், ஆன்லைன் சமூகங்கள் மற்றும் திறந்த மூல திட்டங்கள் உட்பட கிடைக்கக்கூடிய வளங்களின் செல்வத்தைப் பயன்படுத்த நினைவில் கொள்ளுங்கள். மேப்டு வகைகள் மற்றும் நிபந்தனை வகைகளின் சக்தியைத் தழுவுங்கள், மேலும் சவாலான வகை தொடர்பான சிக்கல்களைக் கூட சமாளிக்க நீங்கள் நன்கு தயாராக இருப்பீர்கள்.