Generic funksiyalar — T parametri, bir nechta parametr

~20 daq · TypeScript · Generics

Birinchi darsda <T> bilan tanishdik. Amalda ko'p hollarda bir nechta tur parametri, cheklov (constraint), arrow funksiya sintaksisi kerak bo'ladi.


Bir nechta tur parametri

Ikkita turli argument — ikkita parametr:

function juftlash<A, B>(birinchi: A, ikkinchi: B): [A, B] {
  return [birinchi, ikkinchi];
}

juftlash("Ali", 25);      // [string, number]
juftlash(true, [1, 2]);   // [boolean, number[]]

Qaytish turi ham generic

function xaritaga<K extends string, V>(
  kalitlar: K[],
  qiymatlar: V[]
): Record<K, V> {
  const natija = {} as Record<K, V>;
  kalitlar.forEach((k, i) => { natija[k] = qiymatlar[i]; });
  return natija;
}

xaritaga(["ism", "email"], ["Jasur", "j@mail.com"]);
// Record<"ism" | "email", string>

Arrow funksiya generic sintaksisi

// Oddiy funksiya
function birinchi<T>(arr: T[]): T { return arr[0]; }

// Arrow funksiya — <T,> yoki <T extends unknown>
const birinchi = <T,>(arr: T[]): T => arr[0];
// TSX faylda <T> alone — JSX bilan chalkashadi, shu uchun <T,>

Tur parametrini ishlatish

// T faqat parametrda
function logla<T>(qiymat: T): T {
  console.log(qiymat);
  return qiymat;
}

// T bir nechta joyda
function aylantir<T>(massiv: T[], fn: (x: T) => T): T[] {
  return massiv.map(fn);
}

aylantir([1, 2, 3], x => x * 2);   // number[]
aylantir(["a", "b"], x => x + "!"); // string[]

Amaliy misol — API wrapper

async function apiFetch<T>(url: string): Promise<T> {
  const res = await fetch(url);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json() as Promise<T>;
}

// Ishlatish
type Foydalanuvchi = { id: number; ism: string };
const user = await apiFetch<Foydalanuvchi>("/api/user/1");
// user: Foydalanuvchi ✅

Generic va o'zaro bog'liq turlar

// Ikkinchi argument birinchining kaliti bo'lishi kerak
function olish<T, K extends keyof T>(ob: T, kalit: K): T[K] {
  return ob[kalit];
}

const user = { id: 1, ism: "Ali", email: "ali@mail.com" };

olish(user, "ism");   // string ✅
olish(user, "id");    // number ✅
olish(user, "yosh");  // ❌ — 'yosh' keyof typeof user emas

Tez-tez uchraydigan xatolar

Generic parametrni ishlatmaslik:

// ❌ — T ishlatilmagan, generic bekor
function fn<T>(x: string): string { return x; }

// ✅ — T ishlatilishi kerak
function fn<T>(x: T): T { return x; }

Juda ko'p tur parametri:

// ❌ — 4+ parametr — tuzilmani qayta ko'ring
function fn<A, B, C, D>(a: A, b: B, c: C, d: D) { ... }

Xulosa

// Bir parametr
function fn<T>(x: T): T { ... }

// Bir nechta
function fn<A, B>(a: A, b: B): [A, B] { ... }

// Arrow (TSX da <T,>)
const fn = <T,>(x: T): T => x;

// Tur bog'liqligi
function olish<T, K extends keyof T>(o: T, k: K): T[K] { return o[k]; }

Keyingi dars

34-dars: Generic interface va type alias