‹ முகப்புக்கு திரும்ப

TypeScript Generics மற்றும் Utility Types: API Response-ஐ தலைவலி இல்லாம Type செய்வது எப்படி?

TypeScript-ல் Generics மற்றும் Utility types பயன்படுத்துவது API response-களைக் கையாளும் போது வேலையை எப்படி எளிதாக்குகிறது என்பதைப் புரிந்துகொள்ள ஒரு நடைமுறை வழிகாட்டி.

Keerthika 6 min read
Google-ல் Follow
Web Dev TypeScript Generics மற்றும் Utility Types: API Response-ஐ தலைவலி இல்லாம Type செய்வது எப்படி? 6 நிமிடம் மீதம் Google-ல் Follow

தமிழ்டெக் AI சுருக்கம்

டைப்ஸ்கிரிப்ட்டில் ஜெனரிக்ஸ் (Generics) என்பது தரவுகளின் வகைகளை (types) ஒரு செயலிக்கு அளவுருவாக (parameter) அனுப்ப உதவும் முக்கிய அம்சமாகும். இது 'any' என்பதைப் பயன்படுத்துவதைத் தவிர்த்து, முழுமையான வகைப் பாதுகாப்பை (type safety) உறுதிசெய்கிறது. ஒரே மாதிரியான கட்டமைப்பு கொண்ட பின்தள ஏபிஐ (Backend API) பதில்களைத் தனித்தனி இடைமுகங்கள் (interfaces) இன்றி ஒரே பொதுவான ஜெனரிக் வார்ப்புருவாகக் கையாளவும், Partial, Pick, Omit, Record போன்ற பயனுள்ள உள்ளமைக்கப்பட்ட வகைகளின் மூலம் திரும்பத் திரும்ப குறியீடு எழுதுவதைத் தவிர்க்கவும் இது உதவுகிறது. டைப்ஸ்கிரிப்ட் தொகுக்கப்பட்ட (compile-time) பின் உலாவியில் இயங்கும்போது இந்த வகை வரையறைகள் இருக்காது என்பதால், ரன்டைமில் (runtime) கிடைக்கும் வெளிப்புறத் தரவுகளை வகை காவல்களின் (Type Guards) மூலம் சரிபார்ப்பது மிக அவசியமாகும். மேலும், ஏபிஐ அழைப்புகளுக்குத் தனிப்பயன் ஜெனரிக் ரேப்பர்களைப் பயன்படுத்துவது பயன்பாடுகள் எதிர்பாராத பிழைகளால் முடங்குவதைத் தடுக்கும். அதே சமயம், தேவை இல்லாத இடங்களில் ஜெனரிக்ஸ்களைப் புகுத்துவது, 'any' அல்லது 'as T' போன்ற அவசர வகை மாற்றங்களைப் பயன்படுத்துவது, மற்றும் 'null', 'undefined' மதிப்புகளைக் கருத்தில் கொள்ளாமல் வடிவமைப்பது போன்ற தவறுகளைத் தவிர்க்க வேண்டும் என இக்கட்டுரை தெளிவுபடுத்துகிறது.

  • Generics மூலம் ஒரே கோடில் பல்வேறு டேட்டா வகைகளுக்கு முழுமையான Type Safety பெறலாம்.
  • Partial, Pick, Omit போன்ற Utility Types புது interface எழுதுவதைத் தடுத்து கோடைச் சுருக்குகின்றன.
  • Runtime-ல் வரும் API டேட்டாவைச் சரிபார்க்க Type Guards (is keyword) பயன்படுத்துவது கட்டாயம்.

AI உதவியுடன் தயாரான சுருக்கம் — தமிழ்டெக் எடிட்டர்ஸ் சரிபார்த்தது.

0:00
0:00
🔒 Listen வசதி subscribers-க்கு மட்டும். Subscribe செய்யுங்கள்

முக்கிய விஷயங்கள்

  • Generics என்பது type-களுக்கான parameter மாதிரி; any போடாமல் முழுமையான type safety தருகிறது.
  • Partial, Pick, Omit, Record போன்ற built-in utility types திரும்பத் திரும்ப புது interface எழுதுவதைத் தவிர்க்கின்றன.
  • Backend API தரும் envelope JSON வடிவத்துக்கு ஒரு பொதுவான Generic interface அமைப்பது best practice.
  • TypeScript கம்பைல் ஆனதும் browser-ல் types இருக்காது; அதனால் runtime-ல் type guards கொண்டு data-வை உறுதி செய்வது அவசியம்.

TypeScript-ல Generics ஏன் தேவைப்படுது?

சென்னை OMR அல்லது தரமணி IT பார்க்ல சாயங்காலம் 4 மணி டீ பிரேக்குக்கு முன்னாடி, பக்கத்து சீட் டெவலப்பர் மானிட்டரை எட்டிப் பார்த்தா பல நேரம் இதே காட்சிதான் இருக்கும். ஸ்கிரீன் முழுக்க <T>, <K extends keyof T>, Promise<ApiResponse<T>>-னு ஆங்கிள் பிராக்கெட்டுகள் வரிசையா நிக்கும். புரியாம குழம்பிப் போய், எதுக்கு வம்புனு டக்குனு any போட்டுட்டு ஃபில்டர் காபி குடிக்க கிளம்பிடுவாங்க.

டுடோரியல்களில் Generics-ஐ சொல்லிக் கொடுக்கும் போது ஏதோ கணக்கு பாடம் மாதிரி சொல்லித்தருவதுதான் இந்த பயத்துக்குக் காரணம். நிஜத்துல Generics ரொம்ப சிம்பிளான ஒரு வேலையைத்தான் பண்ணுது. நாம ஒரு நார்மல் ஃபங்க்ஷனுக்கு வேல்யூவை (Value) ஆர்க்யூமெண்ட்டா அனுப்புறோம் இல்லையா? அதே மாதிரி ஒரு டைப்பை (Type) ஆர்க்யூமெண்ட்டா உள்ளே அனுப்புற டெக்னிக்தான் Generics.

உதாரணத்துக்கு Flipkart அல்லது Swiggy போன்ற ஆப்களில் வெவ்வேறு API எண்ட்பாயிண்ட்கள் இருக்கும். ஆனா எல்லாமே ஒரே மாதிரியான ஸ்டேட்டஸ் கோட், மெசேஜ் பார்மட்லதான் டேட்டாவை ரிட்டர்ன் பண்ணும். ஒவ்வொரு API-க்கும் தனித்தனியா பத்து interface எழுதி டைம் வேஸ்ட் பண்றதுக்கு பதிலா, Generics பயன்படுத்தி ஒரே ஒரு Template-ஐ பல இடங்கள்ல ரீயூஸ் பண்ணிக்கலாம்.

Generic Functions மற்றும் Interfaces-ஐ Real Code-ல எப்படி எழுதுறது?

பெரும்பாலான பேக்கெண்ட் API-கள் டேட்டாவை ஒரு 'Envelope' மாடலில் தான் அனுப்பும். அதாவது success, message, timestamp அப்புறம் data என்கிற கீ-க்குள் தான் நாம் கேட்கும் நிஜமான தகவல் இருக்கும். Profile API-ல user தகவல் வரும், Orders API-ல order விவரங்கள் வரும். டேட்டா மட்டும் மாறும், envelope மாறாது.

இதை ஹேண்டில் பண்ண Generic interface எப்படி எழுதுவது என்று கீழே பாருங்க:

// பொதுவான API Envelope Interface
interface ApiResponse&lt;TData&gt; {
  success: boolean;
  message: string;
  timestamp: number;
  data: TData;
}

// நாம் வாங்கும் தனித்துவமான Model
interface DeliveryStatus {
  trackingId: string;
  carrier: string;
  delivered: boolean;
}

// Generic Helper Function
function createApiResponse&lt;T&gt;(payload: T, message: string): ApiResponse&lt;T&gt; {
  return {
    success: true,
    message,
    timestamp: Date.now(),
    data: payload,
  };
}

// TypeScript தானாகவே DeliveryStatus type-ஐ infer செய்து கொள்ளும்
const deliveryInfo: DeliveryStatus = {
  trackingId: "TN-EXP-8891",
  carrier: "BlueDart",
  delivered: true,
};

const response = createApiResponse(deliveryInfo, "Order dispatched");
console.log(response.data.trackingId);

இங்க <TData> என்பது ஒரு பிளேஸ்ஹோல்டர் மாதிரிதான். நாம DeliveryStatus-ஐ உள்ளே அனுப்பும்போது, data கீ-யின் டைப் தானாகவே DeliveryStatus-ஆக மாறிடுது. இதனால் கோட் அடிக்கும்போதே autocomplete பக்காவாக வேலை செய்யும்.

Utility Types: Partial, Pick, Omit, Record எப்போ யூஸ் பண்ணனும்?

TypeScript-ல் ஏற்கனவே இன்-பில்ட்டாக இருக்கும் Utility types உங்க கோடிங் வேகத்தை பல மடங்கு அதிகரிக்கும். ஒரு பெரிய User Profile interface இருக்குனு வச்சுப்போம். பயனர் தன் விவரங்களை எடிட் பண்ணும்போது எல்லா ஃபீல்டையும் அனுப்ப மாட்டாங்க, பெயரை மட்டும் மாத்தலாம். அதுக்காக தனியா இன்னொரு interface எழுத வேண்டியதில்லை.

நான்கு முக்கியமான Utility types எப்படி வேலை செய்யுதுனு பார்ப்போம்:

interface UserProfile {
  id: string;
  fullName: string;
  email: string;
  phoneNumber: string;
  role: "admin" | "customer" | "delivery_partner";
}

// 1. Partial: எல்லா ஃபீல்ட்களையும் optional (?) ஆக மாற்றும் (Patch update-க்கு சூப்பர்)
type UpdateProfileInput = Partial&lt;UserProfile&gt;;

// 2. Pick: தேவையான குறிப்பிட்ட ஃபீல்ட்களை மட்டும் தேர்வு செய்யும்
type UserSummary = Pick&lt;UserProfile, "id" | "fullName"&gt;;

// 3. Omit: குறிப்பிட்ட தேவையில்லாத ஃபீல்டை மட்டும் நீக்கிவிடும்
type PublicProfile = Omit&lt;UserProfile, "phoneNumber"&gt;;

// 4. Record: Key-Value pair-க்கு ஸ்ட்ரிக்ட் டைப் கொடுக்கும்
type RolePermissions = Record&lt;UserProfile["role"], string[]&gt;;

const permissions: RolePermissions = {
  admin: ["create", "edit", "delete"],
  customer: ["view", "buy"],
  delivery_partner: ["view_orders", "update_status"],
};

இந்த Utility types இல்லேன்னா நம்ம ப்ராஜெக்ட்ல வகைதொகையே இல்லாம ஒரே மாதிரி நூறு interface ஃபைல்கள் குவிஞ்சிடும். இதைத் தவிர்ப்பதுதான் சீனியர் டெவலப்பர்களின் வழக்கம்.

API Fetch Response-க்கு எப்படி Type பண்றது?

பிரவுசரில் இருக்கும் நேட்டிவ் fetch() மெத்தட் எப்போதுமே Promise<any> தான் ரிட்டர்ன் பண்ணும். நாமதான் அதை Generic helper மூலமா டைப்-சேஃப் ஆக மாத்தணும். இல்லையென்றால் UI-ல் டேட்டாவை ரெண்டர் பண்ணும்போது அன்-டிஃபைன்ட் (undefined) எரர் வந்து ஆப்பே க்ராஷ் ஆகும் வாய்ப்பு அதிகம்.

ஒரு கிளீனான fetch wrapper எப்படி எழுதுவது என்பதைப் பாருங்க:

interface UserResponse {
  id: string;
  name: string;
  city: string;
}

async function apiGet&lt;T&gt;(endpoint: string): Promise&lt;T&gt; {
  const response = await fetch(endpoint);
  
  if (!response.ok) {
    throw new Error(`HTTP Error: ${response.status}`);
  }
  
  // json() தரும் data-வை நாம் எதிர்பார்க்கும் generic type ஆக மாற்றுகிறோம்
  const result: T = await response.json();
  return result;
}

async function loadUserData() {
  try {
    const user = await apiGet&lt;UserResponse&gt;("/api/v1/user/me");
    console.log(user.city);
  } catch (error) {
    console.error("API call failed:", error);
  }
}

இப்படி Generic ஃபங்க்ஷனாக மாற்றிவிட்டால், எதிர்காலத்தில் நூறு விதமான API-களுக்கு இதே apiGet ஃபங்க்ஷனை வைத்துக்கொண்டு, வெறும் டைப்பை மட்டும் மாற்றி எளிதாக கால் பண்ணிக்கலாம்.

Runtime-ல Data சரியா இருக்கானு Type Guards வச்சி எப்படி Check பண்ணலாம்?

இங்கதான் பல ஜூனியர் டெவலப்பர்கள் ஏமாறுவாங்க. TypeScript என்பது வெறும் compile-time டூல் மட்டும்தான். உங்க கோட் ஜாவாஸ்கிரிப்டாக மாறி பிரவுசர்ல ஓடும்போது எந்த டைப்பும் அங்க இருக்காது. பேக்கெண்ட் சர்வர் திடீரென id ஃபீல்டே தராமல் தவறான JSON அனுப்பினால், டைப்ஸ்கிரிப்ட் அதை பிரவுசரில் தடுத்து நிறுத்தாது.

அதனாலதான் வெளி உலகத்திலிருந்து (API, LocalStorage) வரும் டேட்டாவை நம்புறதுக்கு முன்னாடி Type Guard வெச்சு செக் பண்ணனும். இதற்கு is என்கிற கீவேர்ட் பயன்படும்:

interface PaymentStatus {
  transactionId: string;
  amount: number;
  status: "SUCCESS" | "FAILED";
}

// Custom Type Guard: payload சரியான வடிவில் உள்ளதா என runtime-ல் சரிபார்க்கிறது
function isPaymentStatus(data: unknown): data is PaymentStatus {
  return (
    typeof data === "object" &amp;&amp;
    data !== null &amp;&amp;
    "transactionId" in data &amp;&amp;
    "amount" in data &amp;&amp;
    typeof (data as PaymentStatus).transactionId === "string" &amp;&amp;
    typeof (data as PaymentStatus).amount === "number"
  );
}

function handleCallback(rawData: unknown) {
  if (isPaymentStatus(rawData)) {
    // இந்த block-க்குள் rawData தானாகவே PaymentStatus ஆக மாறிவிடும்
    console.log(`Paid ₹${rawData.amount} via TXN: ${rawData.transactionId}`);
  } else {
    console.error("Invalid payload received from payment gateway!");
  }
}

Razorpay, Cashfree போன்ற பேமண்ட் கேட்வேக்களின் webhook அல்லது response-களைக் கையாளும்போது இந்த மாதிரியான runtime guards கண்டிப்பா இருக்கணும்.

Generics எழுதும்போது Developers பண்ற Common Mistakes என்ன?

முதல் தப்பு, தேவையில்லாத இடத்துல எல்லாம் Generic-ஐ திணிப்பது. ஒரு ஃபங்க்ஷன் ஒரே ஒரு குறிப்பிட்ட டைப்பை மட்டும்தான் வாங்கப் போகுதுனா, அங்க போயிட்டு <T> போடக்கூடாது. கோட் படிக்கவே பயங்கர சிக்கலாகிடும்.

ரெண்டாவது தப்பு, டைப் எரர் வந்த உடனே (data as any) அல்லது அவசரத்துல as T என்று டைப் அஸர்ஷன் பண்ணி தப்பிப்பது. இது டைப்ஸ்கிரிப்ட்டின் பாதுகாப்பையே காலி பண்ணிடும்.

மூணாவது தப்பு, Null மற்றும் Undefined வேல்யூக்களைக் கணக்கில் எடுக்காமல் Generic Envelope டிசைன் பண்ணுவது. பேக்கெண்ட் சில சமயம் data: null என அனுப்பும்போது உங்கள் ஃபிரண்ட் எண்ட் UI உடையும்.

Indian Tech Interview-ல இது எப்படி கேப்பாங்க? சின்ன Practice Task!

சென்னை, பெங்களூரு ஸ்டார்ட்அப்கள் அல்லது சர்வீஸ் கம்பெனிகளில் Frontend / Fullstack இன்டர்வியூ போனீங்கனா, மூணாவது ரவுண்ட்ல Generics பத்தி கண்டிப்பா ஒரு ரியல்-டைம் கேள்வி வரும். 'ஒரு Generic Pagination Response-ஐ டிசைன் பண்ணி, அதை ஒரு fetch function-ல wrap பண்ணுங்க' என்பதுதான் பல இன்டர்வியூவர்ஸின் ஃபேவரிட் டாஸ்க்.

உங்களுக்கான பிராக்டிஸ் டாஸ்க் இதோ: PaginatedResponse<T> என்ற interface-ஐ உருவாக்குங்கள். அதில் items: T[], totalCount: number, page: number, மற்றும் hasMore: boolean இருக்க வேண்டும். பின்னர் தயாரிப்புப் பொருட்களின் பட்டியல் (Product list) ஒன்றுக்கு இந்த interface-ஐப் பயன்படுத்தி ஒரு மாதிரி கோட் எழுதி இயக்கிப் பாருங்கள். கைக்கு பழகிவிட்டால் Generics பயம் அடியோடு போயிடும்!

அடிக்கடி கேட்கப்படும் கேள்விகள்

3

Generics எப்போது பயன்படுத்த வேண்டும்?

ஒரே லாஜிக் அல்லது interface வெவ்வேறு டேட்டா வகைகளுடன் மீண்டும் மீண்டும் பயன்படும் போது (உதாரணமாக API wrapper-கள், cache handlers) Generics பயன்படுத்த வேண்டும்.

TypeScript Utility types என்றால் என்ன?

ஏற்கனவே இருக்கும் ஒரு interface அல்லது type-ஐ அடிப்படையாக வைத்து, அதன் ஃபீல்டுகளை சுலபமாக மாற்றியமைக்க TypeScript தரும் ரெடிமேட் டூல்கள்தான் Partial, Pick, Omit, Record போன்றவை.

any-க்கும் unknown-க்கும் என்ன வித்தியாசம்?

any போட்டால் TypeScript எந்த செக்கிங்கும் பண்ணாது; type safety காலியாகிவிடும். ஆனால் unknown போட்டால் runtime-ல் டேட்டாவின் type-ஐ உறுதி செய்த பிறகே அதன் properties-ஐ அணுக முடியும்.

நாளைய டெக் செய்திகள் உங்க WhatsApp-க்கே

தினமும் ஒரு சின்ன update, இலவசம். TamilTech channel-ஐ follow பண்ணுங்க.

What do you think?

people reacted

Keerthika

தமிழ்டெக் எடிட்டோரியல் டீம் · 3,653 கட்டுரைகள்

Keerthika is an editor at TamilTech, the Tamil and English technology publication founded by Praveen Kumar S. She covers AI, smartphones, gadgets, EVs, startups and cybersecurity i...

மேலும் Keerthika

WhatsApp-ல் TamilTech-ஐக் கேளுங்க

டெக் சந்தேகமா? தமிழிலோ ஆங்கிலத்திலோ கேளுங்க — எங்க WhatsApp அசிஸ்டன்ட் TamilTech கட்டுரைகளில் இருந்து சில நொடிகளில் பதில் சொல்லும்.

தொடர்புடைய செய்திகள்

கருத்துகள் (0)

| Supports **bold**, *italic*, `code`

Be the first to comment!

அடுத்த செய்தி API அப்படின்னா என்ன? REST, HTTP Methods மற்றும் Status Codes எளிய விளக்கம்
TamilTech

TamilTech

Install app for faster access

Earn XP 🏆
WhatsApp
Notifications