7.3-bob: Funksiyalar va Generics (chuqur)
7-QISM — TypeScript · 3-mavzu
1. Kirish va motivatsiya
Turlar asosini 7.2-bob bildik. Endi ikki muhim mavzuga o'tamiz: funksiya turlari (parametr, qaytish, overload — chuqur) va TS'ning eng kuchli, eng zarur xususiyati — generics (generiklar — turlarni parametrlash). Generics — boshlovchilar uchun eng "qo'rqinchli" ko'rinadigan, lekin eng kuchli TS xususiyati. Uni o'zlashtirish — TS'da "o'rta"dan "professional"ga o'tish belgisi.
Funksiyalar — har kodning asosi (3-bob: 2.3-JS). TS'da funksiya parametr turlari va qaytish turi bilan ta'riflanadi — bu funksiyani xavfsiz va o'z-o'zini hujjatlaydigan qiladi. Lekin ba'zan funksiya turli turlar bilan ishlashi kerak (masalan, "massivning birinchi elementini qaytar" — number massivi uchun ham, string massivi uchun ham). Bunda any ishlatish — tur xavfsizligini yo'qotadi. Yechim — generics.
Generics — turni parametr sifatida qabul qilish (<T>). Funksiya/class/interface aniq tur bilan emas, o'zgaruvchi tur (T) bilan ishlaydi — ishlatishda aniq tur beriladi. Masalan, birinchi<T>(arr: T[]): T — istalgan turdagi massiv bilan ishlaydi, lekin tur saqlangan (number massiviga number qaytaradi). Bu — Array<T>, Promise<T>, Repository<T> 6.13-bob, useState<T> 11.4-bob — hamma joyda. Generics'siz zamonaviy TS yo'q. Bu bob: funksiya turlari, generics (funksiya/class/interface), constraints — chuqur.
O'xshatish (generics): generic — universal idish/qolip. Oddiy idish (aniq tur) faqat bir narsa uchun (faqat suv idishi). Generic idish (
Container<T>) — istalgan narsa uchun (suv, sut, asal —Container<Suv>,Container<Sut>), lekin har biri o'z turini saqlaydi (sut idishidan sut chiqadi, suv emas). Yoki: qolip (<T>) — bir xil shakl, lekin turli material (plastik, metall) bilan to'ldiriladi — har biri o'z xususiyatini saqlaydi.
Nega muhim?
- Qayta ishlatish + xavfsizlik — generics turli tur bilan, lekin tur saqlangan.
- Stack'da hamma joyda — Array/Promise/Repository/useState — generics.
- Professional TS — generics'siz murakkab TS yozib bo'lmaydi.
- ORM/React — Prisma, TypeORM, React hooks — generics asosida.
2. Nazariya — chuqur tushuntirish
2.1. Funksiya turlari (parametr, qaytish)
// Parametr turlari + qaytish turi (7.2: 2.6)
function summa(a: number, b: number): number {
return a + b;
}
// Arrow function (2.3-JS)
const kvadrat = (n: number): number => n * n;
// Qaytish turini inference qiladi (yozmasa ham — lekin yozish hujjat)
function ko'paytir(a: number, b: number) { // qaytish: number (inference)
return a * b;
}Funksiya turi: parametr turlari majburiy (inference yo'q parametrlarga — strict — 7.1: 2.8). Qaytish turi — inference qilinadi, lekin yozish tavsiya (hujjat + xato oldini oladi — funksiya kutilgan turni qaytaradimi).
2.2. Ixtiyoriy, default, rest parametrlar
// Ixtiyoriy parametr (? — oxirida)
function salom(ism: string, familiya?: string): string {
return familiya ? `${ism} ${familiya}` : ism;
}
// Default qiymat
function ko'paytir(a: number, b: number = 2): number { // b default 2
return a * b;
}
// Rest parametr (... — qolganlari massiv — 2.8-JS)
function yig'indi(...sonlar: number[]): number {
return sonlar.reduce((s, n) => s + n, 0);
}
yig'indi(1, 2, 3, 4); // 10Parametr turlari:
?(ixtiyoriy —undefinedbo'lishi mumkin);= qiymat(default — berilmasa);...rest(qolganlari massiv — 2.8-JS). Ixtiyoriy oxirida bo'lishi kerak (majburiydan keyin).
2.3. Funksiya turi (type) va callback
// Funksiya turini alohida ta'riflash (7.2: 2.11)
type MatematikAmal = (a: number, b: number) => number;
const summa: MatematikAmal = (a, b) => a + b; // a, b — inference (number)
// Callback turi (parametr sifatida)
function ishla(data: number[], callback: (n: number) => void): void {
data.forEach(callback);
}
// Async funksiya — Promise qaytaradi (2.11-JS)
async function userOl(id: number): Promise<User> { // Promise<User>
return { id, ism: "Ali" };
}Funksiya turi (
(a: number) => number) — funksiyani parametr/o'zgaruvchi sifatida. Callback (3-bob: 2.3-JS) — tur bilan xavfsiz. Async —Promise<T>qaytaradi (2.11-JS, 5.1). Bu — har joyda (event handler, callback, async).
2.4. Function overload (bir nom, ko'p signatura)
// Overload — bir funksiya, turli parametr/qaytish (signatura'lar)
function ol(id: number): User; // signatura 1
function ol(email: string): User; // signatura 2
function ol(arg: number | string): User { // amalga oshirish (bitta)
if (typeof arg === "number") return { id: arg, ism: "Ali" };
return { id: 1, ism: "Ali" }; // email bo'yicha
}
ol(1); // User (number signatura)
ol("a@b.uz"); // User (string signatura)Overload — bir funksiya turli xil chaqirilishi (har xil parametr/qaytish). Signaturalar (e'lon) + bitta amalga oshirish. Kamdan-kam kerak (ko'pincha union/generic afzal), lekin ba'zi API'larda (turli kirish — turli chiqish).
2.5. Generics — muammo va yechim
Muammo: funksiya turli turlar bilan ishlashi kerak, lekin tur saqlanishi kerak:
// any — tur yo'qoladi (7.1: 2.9)
function birinchiAny(arr: any[]): any {
return arr[0];
}
const x = birinchiAny([1, 2, 3]); // x: any (number ekanini bilmaydi!)
// Generic — tur SAQLANADI
function birinchi<T>(arr: T[]): T { // T — tur parametri
return arr[0];
}
const y = birinchi([1, 2, 3]); // y: number (TS biladi!)
const z = birinchi(["a", "b"]); // z: stringGenerics yechimi:
<T>— tur parametri (turni keyin aniqlaydi).birinchi<T>(arr: T[]): T— "istalgan T turdagi massiv, T qaytaradi".anydan farqi: tur saqlanadi (number massivi number). Bu — qayta ishlatish + tur xavfsizligi birga.
2.6. Generic sintaksisi va inference
function o'rab<T>(qiymat: T): T[] { // T — tur parametri (<> ichida)
return [qiymat];
}
// Inference — TS T ni xulosa qiladi (yozmasa ham)
o'rab(5); // T = number (avtomatik)
o'rab("salom"); // T = string
// Aniq belgilash (kerak bo'lsa)
o'rab<number>(5); // T = number (aniq)Generic inference: ko'pincha
Tni yozmasa ham bo'ladi — TS argumentdan xulosa qiladi (o'rab(5)T = number). Aniq belgilash — noaniq holatda (o'rab<string>()).<T>— konvensiya (T = Type; K = Key, V = Value, E = Element).
2.7. Ko'p generic parametr
// Ikki tur parametri
function juftlik<K, V>(kalit: K, qiymat: V): [K, V] {
return [kalit, qiymat];
}
juftlik("yosh", 25); // [string, number]
// Obyekt birlashtirish
function birlashtir<T, U>(a: T, b: U): T & U { // intersection (7.2: 2.12)
return { ...a, ...b };
}
const r = birlashtir({ ism: "Ali" }, { yosh: 25 }); // { ism: string, yosh: number }Bir nechta tur parametri (
<K, V>,<T, U>) — turli turlarni bog'lash. Map (Map<K, V>), juftlik, birlashtirish. Har parametr mustaqil xulosa qilinadi.
2.8. Generic constraints (extends — cheklov)
Ba'zan generic turga shart kerak (masalan, "T'da length bo'lishi kerak"):
// T istalgan tur — length bo'lmasligi mumkin
function uzunlik<T>(x: T): number {
// return x.length; // "length T'da yo'q bo'lishi mumkin"
}
// Constraint — T length'li bo'lishi SHART (extends)
function uzunlik<T extends { length: number }>(x: T): number {
return x.length; // OK (T'da length bor — kafolat)
}
uzunlik("salom"); // 5 (string'da length bor)
uzunlik([1, 2, 3]); // 3 (array'da length bor)
// uzunlik(42); // (number'da length yo'q)Constraint (
T extends X) — generic turni cheklaydi (T X'ga mos bo'lishi shart).T extends { length: number }— "T'da length bo'lsin". Bu — generic'ga ishonch beradi (T'ning xususiyatlarini ishlatish mumkin). Eng ko'p ishlatiladigan generic xususiyati.
2.9. keyof va generic (kalit bo'yicha)
// keyof — obyekt kalitlari turi (7.4'da chuqur)
function ol<T, K extends keyof T>(obj: T, kalit: K): T[K] {
return obj[kalit]; // T[K] — kalitning qiymat turi
}
const user = { ism: "Ali", yosh: 25 };
ol(user, "ism"); // string (T["ism"])
ol(user, "yosh"); // number (T["yosh"])
// ol(user, "boshqa"); // "boshqa" — user kaliti emas
keyof T— obyekt kalitlari turi ("ism" | "yosh").K extends keyof T— K obyekt kaliti bo'lishi shart.T[K]— kalitning qiymat turi. Bu — tur-xavfsiz obyekt kirishi (lodashget, ORMselect). Kuchli, lekin 7.4'da chuqurroq.
2.10. Generic interface va type
// Generic interface (7.2: 2.5)
interface Quti<T> {
qiymat: T;
ol(): T;
}
const sonQuti: Quti<number> = { qiymat: 5, ol() { return this.qiymat; } };
// Generic type (7.2: 2.11)
type Natija<T> = { success: true; data: T } | { success: false; xato: string };
// Generic + default
interface API<T = unknown> { // default tur (berilmasa unknown)
data: T;
status: number;
}Generic interface/type — qayta ishlatiladigan tipli tuzilma.
Quti<T>— istalgan tur uchun quti.Natija<T>— API javob (data turi o'zgaradi).<T = unknown>— default tur (berilmasa). Bu — Prisma, React kabi kutubxonalarning asosi.
2.11. Generic class (6.13 bilan)
// Generic class — Repository pattern (6.13: 2.7, 9)
class Repository<T extends { id: number }> { // constraint: T'da id bor (2.8)
private items: T[] = [];
topId(id: number): T | undefined {
return this.items.find((item) => item.id === id);
}
qo'sh(item: T): void {
this.items.push(item);
}
}
interface User { id: number; ism: string; }
const userRepo = new Repository<User>(); // T = User
userRepo.qo'sh({ id: 1, ism: "Ali" });
const u = userRepo.topId(1); // User | undefined (tipli!)Generic class — turli turlar uchun bir class (Repository
, Repository ). T extends { id: number }— constraint (T'da id kerak). Bu — TypeORM Repository 6.13-bob, umumiy CRUD class. Qayta ishlatish + tur xavfsizligi.
2.12. Built-in generics (Array, Promise, ...)
JS/TS'ning ko'p tuzilmasi — generic (allaqachon ishlatgansiz):
Array<number> // number[] (massiv)
Promise<User> // async natija (2.11-JS)
Map<string, number> // kalit-qiymat (2.9-JS)
Set<string> // to'plam (2.9-JS)
Record<string, User> // obyekt (utility — 7.4)Siz generics'ni allaqachon ishlatgansiz:
Promise<User>5.1-bob,Array<T>,Map<K,V>(2.9-JS). Bular — built-in generics. Tushunganingizdan keyin — o'zingiz yozasiz. ReactuseState<T>11.4-bob ham generic.
2.13. Generic utility funksiyalar
// Tur-xavfsiz utility'lar (qayta ishlatiladigan)
function oxirgi<T>(arr: T[]): T | undefined {
return arr[arr.length - 1];
}
function guruhla<T, K extends string | number>(
arr: T[], kalitFn: (item: T) => K
): Record<K, T[]> { // Record (7.4)
return arr.reduce((acc, item) => {
const kalit = kalitFn(item);
(acc[kalit] ??= []).push(item);
return acc;
}, {} as Record<K, T[]>);
}
// guruhla(users, u => u.rol) { admin: [...], user: [...] } (tipli)Generic utility'lar — turli tur bilan ishlaydigan, tur-xavfsiz yordamchilar (lodash kabi).
oxirgi<T>,guruhla<T, K>— qayta ishlatiladigan. Bu — real loyihada generics'ning amaliy foydasi.
2.14. Generic best practices
any o'rniga generic (tur saqlanadi — 2.5)
Inference'dan foydalaning (T ni yozmang — 2.6)
Constraint (extends) kerak bo'lganda (T'ni cheklash — 2.8)
Ma'noli nom (T, K, V — yoki to'liq: TData, TKey)
Ortiqcha generic'dan qoching (kerak bo'lsa — qachon turlar bog'liq)
Default tur (<T = unknown>) — qulaylik 2.10-bob
Built-in generics'ni bil (Array/Promise/Map — 2.12)Generic'ni ortiqcha ishlatmang: generic — turlar bog'liq bo'lganda (kirish turi chiqish turini belgilaydi). Agar tur bog'liq bo'lmasa — generic keraksiz (oddiy tur yetadi). "Har joyga
" — yomon (murakkablik).
2.15. Generics qachon kerak (xulosa)
Generic KERAK:
Funksiya/class turli tur bilan ishlaydi, lekin tur SAQLANISHI kerak
Kirish turi chiqish turini belgilaydi (birinchi<T>(arr): T)
Konteyner/wrapper (Quti<T>, Repository<T>, Promise<T>)
Qayta ishlatiladigan utility (turli tur)
Generic KERAK EMAS:
Tur aniq va o'zgarmas (oddiy tur yetadi)
Turlar bog'liq emas (any'ni yashirish uchun emas)3. Sintaksis — tez ma'lumotnoma
// Funksiya (2.1-2.3)
function f(a: number, b?: string, c = 10): number { return a; }
type Fn = (x: number) => string;
async function g(): Promise<User> { ... }
// Generics (2.5-2.11)
function birinchi<T>(arr: T[]): T { return arr[0]; } // funksiya
interface Quti<T> { qiymat: T; } // interface
class Repo<T extends { id: number }> { ... } // class + constraint
function ol<T, K extends keyof T>(o: T, k: K): T[K] { ... } // keyof (2.9)4. Batafsil kod namunalari
Misol 1 — Funksiya turlari (2.1-2.3)
// Parametr + qaytish (2.1)
function chegirma(narx: number, foiz: number): number {
return narx * (1 - foiz / 100);
}
// Ixtiyoriy, default, rest (2.2)
function xabar(matn: string, prefiks = "[INFO]", ...qoshimcha: string[]): string {
return `${prefiks} ${matn} ${qoshimcha.join(" ")}`;
}
// Funksiya turi + callback (2.3)
type Filter<T> = (item: T) => boolean; // generic funksiya turi
function filtrla<T>(arr: T[], fn: Filter<T>): T[] {
return arr.filter(fn);
}
filtrla([1, 2, 3, 4], (n) => n > 2); // [3, 4] (n: number — inference)Misol 2 — Generic asoslari (2.5, 2.6)
// Identity (oddiy generic)
function bir xil<T>(qiymat: T): T {
return qiymat;
}
// Massiv utility'lari (tur saqlangan — 2.5)
function birinchi<T>(arr: T[]): T | undefined { return arr[0]; }
function oxirgi<T>(arr: T[]): T | undefined { return arr.at(-1); }
function teskari<T>(arr: T[]): T[] { return [...arr].reverse(); }
const sonlar = birinchi([1, 2, 3]); // number | undefined
const ismlar = teskari(["a", "b"]); // string[]Misol 3 — Constraints (extends — 2.8)
// T'da id bo'lishi shart (constraint — 2.8)
function topId<T extends { id: number }>(arr: T[], id: number): T | undefined {
return arr.find((item) => item.id === id);
}
interface User { id: number; ism: string; }
interface Product { id: number; nom: string; }
topId<User>([{ id: 1, ism: "Ali" }], 1); // User | undefined
topId<Product>([{ id: 1, nom: "Telefon" }], 1); // Product | undefined
// topId([{ nom: "x" }], 1); // id yo'q (constraint buzildi)Misol 4 — keyof generic (tur-xavfsiz kirish — 2.9)
// Obyekt maydonini tur-xavfsiz olish (2.9)
function ol<T, K extends keyof T>(obj: T, kalit: K): T[K] {
return obj[kalit];
}
const user = { ism: "Ali", yosh: 25, faol: true };
const ism = ol(user, "ism"); // string (T["ism"])
const yosh = ol(user, "yosh"); // number
const faol = ol(user, "faol"); // boolean
// ol(user, "email"); // "email" — user kaliti emas
// Bir necha maydonni olish (pluck)
function pluck<T, K extends keyof T>(arr: T[], kalit: K): T[K][] {
return arr.map((item) => item[kalit]);
}
pluck([user], "ism"); // string[]Misol 5 — Generic interface va type (2.10)
// API javob turi (generic — 2.10)
type ApiResponse<T> =
| { success: true; data: T }
| { success: false; error: string };
async function userOl(id: number): Promise<ApiResponse<User>> {
try {
const user = await fetchUser(id);
return { success: true, data: user }; // data: User
} catch (err) {
return { success: false, error: "Topilmadi" };
}
}
const javob = await userOl(1);
if (javob.success) console.log(javob.data.ism); // narrowing 7.5-bob — data: User
else console.log(javob.error);Misol 6 — Generic class (Repository — 2.11)
// Umumiy CRUD repository (generic class — 2.11, 6.13)
class InMemoryRepository<T extends { id: number }> {
private items = new Map<number, T>(); // Map<number, T> (2.12)
hammasi(): T[] { return [...this.items.values()]; }
topId(id: number): T | undefined { return this.items.get(id); }
saqla(item: T): T { this.items.set(item.id, item); return item; }
ochir(id: number): boolean { return this.items.delete(id); }
}
interface User { id: number; ism: string; }
interface Product { id: number; nom: string; narx: number; }
const userRepo = new InMemoryRepository<User>(); // T = User
const productRepo = new InMemoryRepository<Product>(); // T = Product
userRepo.saqla({ id: 1, ism: "Ali" }); // tipli
const u = userRepo.topId(1); // User | undefinedMisol 7 — Generic utility funksiyalar (2.13)
// guruhla — array'ni kalit bo'yicha guruhlash (2.13)
function guruhla<T, K extends string | number | symbol>(
arr: T[], kalitFn: (item: T) => K
): Record<K, T[]> {
return arr.reduce((acc, item) => {
const kalit = kalitFn(item);
(acc[kalit] ??= []).push(item);
return acc;
}, {} as Record<K, T[]>);
}
const users = [
{ ism: "Ali", rol: "admin" },
{ ism: "Vali", rol: "user" },
{ ism: "Hasan", rol: "admin" },
];
const rolBoyicha = guruhla(users, (u) => u.rol);
// { admin: [Ali, Hasan], user: [Vali] } — tipli!
// noyob — takrorlanmas
function noyob<T>(arr: T[]): T[] {
return [...new Set(arr)]; // Set<T> (2.12)
}
noyob([1, 1, 2, 3, 3]); // [1, 2, 3]Misol 8 — Async generic (Promise — 2.3, 2.12)
// Generic async wrapper (xato boshqaruvi — 5.10 ruhida)
async function xavfsizSorov<T>(
fn: () => Promise<T>
): Promise<{ data: T; xato: null } | { data: null; xato: Error }> {
try {
const data = await fn();
return { data, xato: null }; // muvaffaqiyat
} catch (err) {
return { data: null, xato: err as Error }; // xato
}
}
// Ishlatish (tur saqlangan)
const natija = await xavfsizSorov(() => fetchUser(1)); // data: User | null
if (natija.data) console.log(natija.data.ism); // narrowing (7.5)5. To'g'ri va noto'g'ri holatlar
1) any o'rniga generic
// any — tur yo'qoladi (2.5)
function birinchi(arr: any[]): any { return arr[0]; }
// generic — tur saqlanadi
function birinchi<T>(arr: T[]): T { return arr[0]; }2) Generic'ni ortiqcha ishlatish
// keraksiz generic (turlar bog'liq emas — 2.14)
function salom<T>(ism: string): string { return ism; }
// oddiy tur (T kerak emas)
function salom(ism: string): string { return ism; }3) Constraint'siz xususiyatga murojaat
// T'da length bo'lmasligi mumkin (2.8)
function uzunlik<T>(x: T) { return x.length; } // xato
// constraint
function uzunlik<T extends { length: number }>(x: T) { return x.length; }4) Qaytish turini yozmaslik (muhim funksiya)
// noaniq qaytish (xato o'tib ketadi)
function hisobla(a: number) { return a > 0 ? a : "manfiy"; } // number | string (kutilmagan?)
// aniq qaytish turi (xato ushlanadi)
function hisobla(a: number): number { return a > 0 ? a : -a; }5) Ko'p inference o'rniga aniq belgilash (noaniq)
// Bo'sh massiv — inference bilmaydi
const arr = []; // any[] (yomon)
const arr2: number[] = []; // aniq6. Keng tarqalgan xatolar va yechimlari
Xato 1 — Property 'x' does not exist on type 'T'
Sababi: generic T'da xususiyat bo'lmasligi mumkin (constraint yo'q — 2.8). Yechimi: T extends { x: ... } (constraint).
Xato 2 — Argument of type 'X' is not assignable to parameter
Sababi: tur mos emas, yoki constraint buzildi 2.8-bob. Yechimi: to'g'ri tur; constraint'ga mos argument.
Xato 3 — Generic tur unknown/noaniq
Sababi: inference ishlamadi (bo'sh massiv, noaniq). Yechimi: aniq belgilash (birinchi<number>(...)).
Xato 4 — 'T' is declared but never used
Sababi: generic e'lon qilindi, lekin ishlatilmadi (keraksiz — 2.14). Yechimi: generic'ni olib tashlang (oddiy tur).
Xato 5 — Funksiya kutilmagan tur qaytaradi
Sababi: qaytish turi yozilmagan (inference noto'g'ri — 2.1). Yechimi: aniq qaytish turi (xato ushlanadi).
Xato 6 — keyof xatosi
Sababi: K extends keyof T constraint yo'q 2.9-bob. Yechimi: constraint qo'sh; kalit obyektga mos.
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- Funksiyalar (2.3-JS): TS funksiya turlari.
- Turlar 7.2-bob: generic — turlar ustida.
- Ilg'or turlar 7.4-bob: keyof, mapped — generic bilan.
- Promise/async (2.11-JS, 5.1): Promise
. - Map/Set (2.9-JS): Map<K,V>, Set
. - TypeORM 6.13-bob: Repository
. - React 11.4-bob: useState
, hooks. - Zod 5.9-bob: infer
. - Utility funksiyalar: lodash kabi generic.
- SOLID (9): generic interface (DIP).
8. Eng yaxshi amaliyotlar (best practices)
anyo'rniga generic (tur saqlanadi — 2.5).- Inference'dan foydalaning (T ni yozmang, kerak bo'lsa belgilang — 2.6).
- Constraint (extends) kerak bo'lganda (T'ni cheklash — 2.8).
- Qaytish turini yozing (muhim funksiya — hujjat + xato — 2.1).
- Ortiqcha generic'dan qoching (turlar bog'liq bo'lganda — 2.14).
- Ma'noli generic nom (T, K, V yoki TData — 2.14).
- Default tur (<T = unknown> — qulaylik — 2.10).
- Built-in generics'ni biling (Array/Promise/Map/Record — 2.12).
- keyof bilan tur-xavfsiz kirish (obyekt maydoni — 2.9).
- Generic class — qayta ishlatiladigan (Repository — 2.11).
9. Amaliy loyiha: "Generic Utility Kutubxonasi"
Funksiya turlari va generics'ni mustahkamlash.
Maqsad
Tur-xavfsiz, qayta ishlatiladigan generic utility'lar va generic repository class yaratish.
Talablar (requirements)
- Funksiya turlari: parametr/qaytish/ixtiyoriy/default/rest (Misol 1, 2.1, 2.2).
- Array utility'lar (generic): birinchi, oxirgi, teskari, noyob (Misol 2, 7, 2.5).
- Constraint: topId (T extends {id}), uzunlik (Misol 3, 2.8).
- keyof: ol/pluck (tur-xavfsiz maydon — Misol 4, 2.9).
- Generic interface/type: ApiResponse
(Misol 5, 2.10). - Generic class: InMemoryRepository
(CRUD — Misol 6, 2.11). - guruhla: kalit bo'yicha guruhlash (Misol 7, 2.13).
- Async generic: xavfsizSorov (Misol 8, 2.3).
- Built-in generics: Map/Set/Promise ishlatilgan 2.12-bob.
- strict: any'siz, tur saqlangan 7.1-bob.
Maslahatlar (hint)
- any o'rniga
<T>(2.5, 1-xato). - Constraint:
T extends {...}(2.8, 1-xato). - keyof:
K extends keyof T,T[K]2.9-bob. - Inference (T ni yozma — 2.6).
- Ortiqcha generic'dan qoch (2.14, 2-xato).
- Record<K, T[]> (guruhlash — 7.4).
"Tayyor" mezonlari (acceptance criteria)
- Funksiya turlari (ixtiyoriy/default/rest).
- Generic array utility'lar (tur saqlangan).
- Constraint (extends).
- keyof (tur-xavfsiz kirish).
- Generic interface/type (ApiResponse).
- Generic class (repository).
- guruhla (Record).
- Async generic.
- Built-in generics.
- any'siz, strict.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda funksiya turlari va generics'ni chuqur o'rgandik:
- Funksiya turlari (parametr/qaytish — 2.1; ixtiyoriy/default/rest — 2.2; funksiya turi/callback — 2.3; overload — 2.4).
- Generics (
<T>— tur parametri — muammo/yechim — 2.5); inference 2.6-bob; ko'p parametr 2.7-bob; constraints (T extends X— 2.8); keyof 2.9-bob. - Generic interface/type/class (2.10, 2.11); built-in (Array/Promise/Map — 2.12); generic utility'lar 2.13-bob.
- Qachon generic (turlar bog'liq — saqlanishi kerak — 2.15); ortiqcha qochish 2.14-bob.
Keyingi bob — 7.4-bob: Ilg'or turlar — union, intersection, conditional, mapped, utility types. Generics'ni bildik; endi TS'ning eng kuchli, "sehrli" qismiga — ilg'or turlarga — o'tamiz: conditional types (shartli tur), mapped types (tur o'zgartirish), va utility types (Partial, Pick, Omit, Record — tayyor kuchli vositalar). Bu — TS'ni "ekspert" darajaga olib chiqadi.
Foydalanilgan rasmiy/ishonchli manbalar
- typescriptlang.org — Functions, Generics, Generic Constraints, keyof
- TypeScript Handbook — More on Functions, Generics; built-in generic types
- TS docs — generic classes, generic interfaces, constraints
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!