WisarWisar
Dasturlash kitobi/7-QISM — TypeScript20 daqiqa

7.4-bob: Ilg'or turlar — union, intersection, conditional, mapped, utility types

7-QISM — TypeScript · 4-mavzu


1. Kirish va motivatsiya

Turlar 7.2-bob va generics 7.3-bob ni bildik. Endi TS'ning eng kuchli, "sehrli" qismiga — ilg'or turlarga — o'tamiz. Bu mavzu TS'ni boshqa tillardan keskin ajratadi: TS turlar tizimi shunchalik kuchliki, u turlar ustida hisoblash qiladi (turdan yangi tur yasash). Conditional types (shartli tur), mapped types (tur o'zgartirish), va utility types (Partial, Pick, Omit, Record — tayyor kuchli vositalar) — bu TS'ni "o'rta"dan "ekspert" darajaga olib chiqadi.

Asosiy g'oya: ilg'or turlar bilan mavjud turdan yangi tur yasaysiz (qo'lda yozmasdan). Masalan, User interface bor; undan "hamma maydoni ixtiyoriy" versiyasini (Partial<User> — update uchun), yoki "faqat ism va email" versiyasini (Pick<User, "ism" | "email">), yoki "parolsiz" versiyasini (Omit<User, "parol"> — API javob uchun) — bir qatorda yasaysiz. Bu — DRY (takrorlamaslik), va turlar avtomatik sinxron (User o'zgarsa, hosilalar ham).

Bu — real loyihada juda ko'p ishlatiladi: API DTO'lar (NestJS — 8.5), form turlari (React — 11.10), DB modellaridan turli ko'rinishlar (Prisma — 6.12). Utility types'ni bilmasdan, har bir ko'rinishni qo'lda yozasiz (takror, xato, sinxronsiz). Bu bob: union/intersection (chuqurroq), conditional types (extends ? :), mapped types ([K in keyof T]), utility types (tayyor), va template literal types — chuqur. TS'ning eng kuchli, lekin eng ko'p qo'rqitadigan qismi.

O'xshatish: ilg'or turlar — turlar uchun funksiyalar. Oddiy funksiya qiymatdan qiymat yasaydi (summa(2, 3) 5). Ilg'or tur turdan tur yasaydi (Partial<User> ixtiyoriy User). Pick, Omit, Partial — "tur funksiyalari" (kirish: tur, chiqish: yangi tur). Bir marta User yozing, undan o'nlab "ko'rinish" avtomatik (zavoddagi bir qolipdan turli mahsulot).

Nega muhim?

  • DRY — bir turdan ko'p ko'rinish (qo'lda takrorlamasdan).
  • Sinxronlik — asosiy tur o'zgarsa, hosilalar avtomatik.
  • Real loyiha — DTO, form, API javob — utility types bilan.
  • Ekspert TS — bu turlarni bilish — senior TS belgisi.

2. Nazariya — chuqur tushuntirish

2.1. Union va intersection (chuqurroq — 7.2 takrori)

ts
// Union (|) — biri (7.2: 2.4)
type ID = number | string;
type Holat = "yangi" | "tasdiqlandi" | "bekor";

// Intersection (&) — hammasi (7.2: 2.12)
type Shaxs = { ism: string };
type Xodim = { lavozim: string };
type Ishchi = Shaxs & Xodim;        // ism + lavozim

7.2'da ko'rdik; bu yerda ilg'or turlarning poydevori. Union — "yoki" (bir nechta turdan biri); intersection — "va" (hammasi birga). Conditional/mapped types ular ustida quriladi.

2.2. Discriminated union (ajratuvchi maydon)

Discriminated union — har variantda umumiy "ajratuvchi" maydon bo'lgan union (eng foydali naqsh):

ts
type Javob =
  | { holat: "muvaffaqiyat"; data: string }       // "holat" — ajratuvchi (discriminant)
  | { holat: "xato"; xabar: string }
  | { holat: "yuklanmoqda" };

function ishla(j: Javob) {
  switch (j.holat) {                               // ajratuvchi bo'yicha (narrowing — 7.5)
    case "muvaffaqiyat": return j.data;            // bu yerda data bor
    case "xato": return j.xabar;                   // bu yerda xabar bor
    case "yuklanmoqda": return "...";
  }
}

Discriminated union — TS'ning eng kuchli naqshlaridan: umumiy literal maydon (holat) bo'yicha TS qaysi variant ekanini biladi (narrowing — 7.5). API javob, Redux action (12), holat mashinasi — hammasida. Toza, tur-xavfsiz.

2.3. keyof va typeof (turdan tur)

ts
// keyof — obyekt kalitlari turi (7.3: 2.9)
interface User { ism: string; yosh: number; email: string; }
type UserKalit = keyof User;        // "ism" | "yosh" | "email" (union)

// typeof — qiymatdan tur
const config = { port: 3000, host: "localhost" };
type Config = typeof config;        // { port: number; host: string }

// Birga: obyekt qiymatidan kalitlar
type ConfigKalit = keyof typeof config;   // "port" | "host"

keyof — obyekt kalitlarini union qiladi ("ism" | "yosh"). typeofqiymatdan tur oladi (config obyektidan tur). Birga — kuchli (qiymatdan tur, turdan kalit). Bu — mapped types 2.5-bob va as const (7.2: 2.11) bilan ishlaydi.

2.4. Indexed access types (T[K] — kalit qiymati)

ts
interface User { ism: string; yosh: number; manzil: { shahar: string } }

type Ism = User["ism"];              // string (kalit qiymat turi)
type Yosh = User["yosh"];            // number
type Shahar = User["manzil"]["shahar"];   // string (ichma-ich)
type IsmYosh = User["ism" | "yosh"]; // string | number (bir necha kalit)

// Massiv element turi
type Sonlar = number[];
type Element = Sonlar[number];       // number (massiv elementi)

T[K] (indexed access) — turning ma'lum kalitidagi qiymat turi (User["ism"] string). Ichma-ich (User["manzil"]["shahar"]). Massiv element turi (T[number]). Bu — generic'larda (7.3: 2.9) va mapped types'da ishlatiladi.

2.5. Mapped types (tur o'zgartirish)

Mapped type — mavjud turning har maydonini o'zgartirib, yangi tur yasaydi (typescriptlang):

ts
interface User { ism: string; yosh: number; email: string; }

// Har maydonni ixtiyoriy qilish (Partial'ning ichki ishi)
type IxtiyoriyUser = {
  [K in keyof User]?: User[K];       // har K kaliti uchun: ixtiyoriy (?)
};
//  { ism?: string; yosh?: number; email?: string }

// Har maydonni readonly qilish
type ReadonlyUser = {
  readonly [K in keyof User]: User[K];
};

Mapped type sintaksisi: [K in keyof T] — "T'ning har K kaliti uchun". User[K] — kalitning qiymat turi 2.4-bob. ?/readonly qo'shish/olib tashlash (-?, -readonly). Bu — utility types'ning ichki mexanizmi 2.7-bob. Mapped type — turlar ustida "tsikl".

2.6. Conditional types (shartli tur)

Conditional type — tur shartga qarab aniqlanadi (turlar uchun "if" — typescriptlang):

ts
type Tekshir<T> = T extends string ? "matn" : "boshqa";
type A = Tekshir<string>;     // "matn"
type B = Tekshir<number>;     // "boshqa"

// Foydali: null/undefined olib tashlash
type NonNull<T> = T extends null | undefined ? never : T;
type C = NonNull<string | null>;   // string (null olib tashlandi)

// Array element turi
type Element<T> = T extends (infer U)[] ? U : never;   // infer (2.7)
type D = Element<number[]>;    // number

Conditional type (T extends X ? A : B) — "agar T X'ga mos bo'lsa A, aksincha B" (turlar uchun if-else). never — "hech narsa" (olib tashlash). Bu — turlar ustida shartli mantiq. Murakkab, lekin kuchli (utility types ichida).

Distributive conditional (union ustida tarqalish). Agar conditional turning tekshiriladigan turi naked generic (T, qavssiz) va union bo'lsa, TS shartni union'ning har bir a'zosiga alohida qo'llaydi, keyin natijalarni yana union qiladi:

ts
type Yolg'iz<T> = T extends any ? T[] : never;
type A = Yolg'iz<string | number>;   // string[] | number[]  (har a'zoga alohida)
//   NOT (string | number)[]  — bu distributive xatti-harakat

// Distributive'ni O'CHIRISH — T'ni qavsga ol ([T] extends [X])
type Yolg'izmas<T> = [T] extends [any] ? T[] : never;
type B = Yolg'izmas<string | number>;   // (string | number)[]  (birga)

Distributive — union ustida "tsikl" (T extends U ? ... har a'zoga alohida). Ba'zan foydali (NonNullable<string | null> union'dan null chiqib ketadi), ba'zan xato manbai. O'chirish: ikkala tomonni ham [] bilan o'rab ([T] extends [X]). Kutilmagan natija (6-bo'lim, Xato 3) — ko'pincha shu distributive.

2.7. infer (turni "tutib olish")

infer — conditional type ichida turni o'zgaruvchiga tutib olish (typescriptlang):

ts
// Funksiya qaytish turini olish (ReturnType'ning ichi)
type Qaytish<T> = T extends (...args: any[]) => infer R ? R : never;
//                                            ^^^^^^^ R ni "tut"
function f(): number { return 5; }
type FQaytish = Qaytish<typeof f>;   // number (f qaytishini tutdi)

// Promise ichidagi tur
type Unwrap<T> = T extends Promise<infer U> ? U : T;
type X = Unwrap<Promise<string>>;    // string

// Array element
type Elem<T> = T extends (infer E)[] ? E : never;
type Y = Elem<boolean[]>;            // boolean

infer — conditional type ichida "noma'lum turni tutib olish" (infer R — "bu yerdagi turni R deb ol"). Funksiya qaytishi, Promise ichi, array elementi — har qanday turning bir qismini ajratish. Bu — eng ilg'or, lekin kuchli (built-in ReturnType, Awaited shunday qilingan).

2.8. Utility types — Partial, Required

Utility types — TS'ning tayyor tur o'zgartiruvchilari (eng ko'p ishlatiladigan — typescriptlang):

ts
interface User { id: number; ism: string; email: string; yosh?: number; }

// Partial<T> — hamma maydon IXTIYORIY (update uchun)
type UserUpdate = Partial<User>;
//  { id?: number; ism?: string; email?: string; yosh?: number }

// Required<T> — hamma maydon MAJBURIY (ixtiyoriyni olib tashlaydi)
type ToliqUser = Required<User>;
//  { id: number; ism: string; email: string; yosh: number } (yosh majburiy)

Partial<T> — hamma maydon ixtiyoriy (PATCH update — faqat o'zgargan maydonlar — 5.7). Required<T> — hamma majburiy. Bular — mapped type 2.5-bob bilan yasalgan tayyor vositalar. Eng ko'p — Partial (update DTO).

2.9. Utility types — Pick, Omit

ts
interface User { id: number; ism: string; email: string; parol: string; }

// Pick<T, K> — FAQAT tanlangan maydonlar
type UserOmma = Pick<User, "id" | "ism" | "email">;
//  { id: number; ism: string; email: string } (parolsiz — tanlangan)

// Omit<T, K> — tanlanganlardan TASHQARI
type UserXavfsiz = Omit<User, "parol">;
//  { id: number; ism: string; email: string } (parol olib tashlangan)

Pick<T, K> — faqat K maydonlari (tanlash). Omit<T, K> — K'dan tashqari (olib tashlash). Ikkalasi — bir turdan qism ko'rinish. Omit<User, "parol"> — API javob (parolsiz — 14, 5.15). Pick — kerakli maydonlar (form). Juda ko'p ishlatiladi.

2.10. Utility types — Record, Readonly

ts
// Record<K, V> — kalit-qiymat obyekt turi (7.2: 2.14)
type Lugat = Record<string, string>;           // { [k: string]: string }
type RolRuxsat = Record<"user" | "admin", string[]>;
//  { user: string[]; admin: string[] }

// Readonly<T> — hamma maydon o'zgarmas
type ReadonlyUser = Readonly<User>;            // hamma maydon readonly

// Boshqa: ReturnType, Parameters, Awaited
type R = ReturnType<typeof someFn>;            // funksiya qaytishi (2.7)
type P = Parameters<typeof someFn>;            // funksiya parametrlari (tuple)
type A = Awaited<Promise<string>>;             // Promise ichi (string)

Record<K, V> — kalit-qiymat obyekt (Record<"user"|"admin", string[]> — rolruxsatlar). Readonly<T> — o'zgarmas. ReturnType/Parameters/Awaited — funksiya/Promise'dan tur (infer bilan — 2.7). Bular — kundalik utility'lar.

2.11. Utility types xulosa (jadval)

text
  ┌──────────────────┬──────────────────────────────────────┐
  │ Utility          │ Nima qiladi                          │
  ├──────────────────┼──────────────────────────────────────┤
  │ Partial<T>       │ hamma maydon ixtiyoriy (update)      │
  │ Required<T>      │ hamma majburiy                       │
  │ Pick<T, K>       │ faqat K maydonlari                   │
  │ Omit<T, K>       │ K'dan tashqari (parolsiz)            │
  │ Record<K, V>     │ kalit-qiymat obyekt                  │
  │ Readonly<T>      │ o'zgarmas                            │
  │ ReturnType<F>    │ funksiya qaytishi                    │
  │ Parameters<F>    │ funksiya parametrlari (tuple)        │
  │ Awaited<P>       │ Promise ichidagi tur                 │
  │ NonNullable<T>   │ null/undefined olib tashlash         │
  └──────────────────┴──────────────────────────────────────┘

2.12. Template literal types (matn turlari)

Template literal types — matn shablonidan tur yasash (template literal — 2.6-JS, lekin turlar uchun):

ts
type Salom = `Salom, ${string}!`;            // "Salom, X!" shaklidagi matn
let s: Salom = "Salom, Ali!";                // OK
// let s2: Salom = "Xayr";                    // 

// Kalitlardan event nomlar
type Event = "click" | "hover";
type Handler = `on${Capitalize<Event>}`;     // "onClick" | "onHover"

// Route turlari
type Method = "GET" | "POST";
type Route = `${Method} /api/${string}`;     // "GET /api/users"

Template literal types — matn shablonidan tur (`on${T}`). Capitalize/Uppercase/Lowercase — built-in matn o'zgartiruvchilar. Foydali: event nomlar (onClick), CSS xususiyatlar, route'lar — tur-xavfsiz matn. Ilg'or, lekin kuchli.

2.13. Custom utility types yasash

ts
// O'z utility'laringni yasash (mapped + conditional — 2.5, 2.6)

// Nullable — hamma maydon null bo'lishi mumkin
type Nullable<T> = { [K in keyof T]: T[K] | null };

// DeepPartial — ichma-ich ixtiyoriy (rekursiv)
type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

// Maydonlarni tanlab o'zgartirish
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
// T, lekin K maydonlari ixtiyoriy

Built-in utility'lar yetmaganda — o'zingiznikini yasaysiz (mapped + conditional + infer — 2.5-2.7). DeepPartial (ichma-ich), Nullable, PartialBy — keng tarqalgan custom utility'lar. Bu — TS turlar tizimining to'liq kuchi.

2.14. Qachon ilg'or turlar (ehtiyot)

text
  Ilg'or turlar KERAK:
   Bir turdan ko'p ko'rinish (DTO, form, API — utility — 2.8-2.10)
   Kutubxona/umumiy kod (generic + conditional)
   DRY (turlarni sinxron tutish)

  Ilg'or turlar EHTIYOT (ortiqcha murakkablik):
   Oddiy holatda (oddiy interface yetadi)
   Hech kim tushunmaydigan "tur sehri" (o'qiladigan emas)
   "Aqlli" turdan ko'ra O'QILADIGAN tur afzal

Ilg'or turlarni ortiqcha ishlatma: utility types (Partial/Pick/Omit) — kundalik (yaxshi). Lekin murakkab conditional/mapped/infer — faqat zarur bo'lganda (kutubxona, umumiy kod). "Hech kim o'qiy olmaydigan tur sehri" — yomon. O'qiladigan kod — birinchi.

2.15. Best practices (14)

text
   Utility types ishlating (Partial/Pick/Omit/Record — qo'lda yozmang — 2.8-2.10)
   Bir turdan hosila (DRY, sinxron — 2.8)
   Omit<T, "parol"> — maxfiy yashir (API javob — 14, 5.15)
   Discriminated union (holat/API javob — 2.2)
   keyof/typeof (turdan tur — 2.3)
   Custom utility — zarur bo'lganda 2.13-bob
   Murakkab tur sehridan qoching (o'qiladigan — 2.14)
   Template literal — tur-xavfsiz matn (event/route — 2.12)

3. Sintaksis — tez ma'lumotnoma

ts
// keyof/typeof 2.3-bob: type K = keyof T; type C = typeof obj;
// Indexed 2.4-bob: T["kalit"]; T[number]
// Mapped 2.5-bob: { [K in keyof T]?: T[K] }
// Conditional 2.6-bob: T extends X ? A : B
// infer 2.7-bob: T extends Promise<infer U> ? U : T

// Utility types (2.8-2.10)
Partial<T>  Required<T>  Pick<T, K>  Omit<T, K>  Record<K, V>  Readonly<T>
ReturnType<F>  Parameters<F>  Awaited<P>  NonNullable<T>

// Template literal 2.12-bob: `on${Capitalize<T>}`

4. Batafsil kod namunalari

Misol 1 — Discriminated union (API javob — 2.2)

ts
// API holatlari (discriminated union — 2.2)
type FetchHolat<T> =
  | { holat: "yuklanmoqda" }
  | { holat: "muvaffaqiyat"; data: T }
  | { holat: "xato"; xabar: string };

function render(holat: FetchHolat<User[]>): string {
  switch (holat.holat) {                          // ajratuvchi (narrowing — 7.5)
    case "yuklanmoqda": return "Yuklanmoqda...";
    case "muvaffaqiyat": return `${holat.data.length} ta foydalanuvchi`;   // data bor
    case "xato": return `Xato: ${holat.xabar}`;   // xabar bor
  }
}
// React state, Redux (12), data fetching — shu naqsh

Misol 2 — keyof, typeof, indexed (2.3, 2.4)

ts
const config = {
  port: 3000,
  host: "localhost",
  db: { url: "postgres://...", pool: 10 },
} as const;                                        // as const (7.2: 2.11)

type Config = typeof config;                       // qiymatdan tur (2.3)
type ConfigKalit = keyof Config;                   // "port" | "host" | "db"
type Port = Config["port"];                        // 3000 (literal — as const)
type DbUrl = Config["db"]["url"];                  // string (ichma-ich — 2.4)

// Tur-xavfsiz config olish
function olConfig<K extends keyof Config>(kalit: K): Config[K] {   // (7.3: 2.9)
  return config[kalit];
}

Misol 3 — Utility types: Partial, Pick, Omit (2.8, 2.9)

ts
interface User {
  id: number;
  ism: string;
  email: string;
  parol: string;
  yosh?: number;
}

// Update DTO — hamma ixtiyoriy (PATCH — 5.7)
type UserUpdate = Partial<Omit<User, "id">>;       // id'siz, qolgani ixtiyoriy
//  { ism?, email?, parol?, yosh? }

// API javob — parolsiz (14, 5.15)
type UserJavob = Omit<User, "parol">;
//  { id, ism, email, yosh? }

// Login — faqat email/parol
type LoginDto = Pick<User, "email" | "parol">;
//  { email, parol }

// Create — id'siz (avto), parol majburiy
type UserCreate = Omit<User, "id">;

Misol 4 — Record va Readonly (2.10)

ts
// Record — rol  ruxsatlar (5.17)
type Rol = "user" | "moderator" | "admin";
const RUXSATLAR: Record<Rol, string[]> = {
  user: ["o'qish"],
  moderator: ["o'qish", "tahrir"],
  admin: ["o'qish", "tahrir", "o'chirish"],
};
// Record har rol uchun string[] majbur qiladi (biri yetishmasa — xato)

// Readonly — config (o'zgarmas)
const config: Readonly<{ port: number; host: string }> = {
  port: 3000, host: "localhost",
};
// config.port = 4000;   //  readonly

Misol 5 — Conditional types va infer (2.6, 2.7)

ts
// Promise ichini ochish (Awaited'ning ichi — 2.7)
type Unwrap<T> = T extends Promise<infer U> ? U : T;
type A = Unwrap<Promise<User>>;        // User
type B = Unwrap<string>;               // string (Promise emas)

// Funksiya qaytishi (ReturnType'ning ichi)
type Qaytish<T> = T extends (...args: any[]) => infer R ? R : never;
async function userOl() { return { id: 1, ism: "Ali" }; }
type UserTur = Awaited<ReturnType<typeof userOl>>;   // { id, ism } (built-in bilan)

// null olib tashlash
type NonNull<T> = T extends null | undefined ? never : T;
type C = NonNull<string | null | undefined>;   // string

Misol 6 — Mapped types (custom — 2.5, 2.13)

ts
interface User { id: number; ism: string; email: string; }

// Custom: hamma maydon nullable (2.13)
type Nullable<T> = { [K in keyof T]: T[K] | null };
type NullableUser = Nullable<User>;
//  { id: number | null; ism: string | null; email: string | null }

// Custom: getter'lar yasash (template literal + mapped — 2.12)
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];   // kalit o'zgartirish
};
type UserGetters = Getters<User>;
//  { getId: () => number; getIsm: () => string; getEmail: () => string }

Misol 7 — Real DTO tizimi (NestJS uslubida — 8.5 ga)

ts
// Bitta entity'dan butun DTO oilasi (utility types — DRY)
interface User {
  id: number;
  ism: string;
  email: string;
  parol: string;
  rol: "user" | "admin";
  createdAt: Date;
}

// Create — avtomatik maydonlarsiz (id, createdAt)
type CreateUserDto = Omit<User, "id" | "createdAt">;

// Update — hamma ixtiyoriy (parolsiz — alohida endpoint)
type UpdateUserDto = Partial<Omit<User, "id" | "createdAt" | "parol">>;

// API javob — parolsiz (14)
type UserResponse = Omit<User, "parol">;

// Ro'yxat — qisqa
type UserListItem = Pick<User, "id" | "ism" | "rol">;

// User o'zgarsa — HAMMA DTO avtomatik yangilanadi (sinxron — DRY!)

Misol 8 — Template literal types (2.12)

ts
// Event handler nomlari (tur-xavfsiz — 2.12)
type EventName = "click" | "focus" | "change";
type HandlerName = `on${Capitalize<EventName>}`;   // "onClick" | "onFocus" | "onChange"

const handlerlar: Record<HandlerName, () => void> = {
  onClick: () => {}, onFocus: () => {}, onChange: () => {},
};

// API route turlari
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type ApiRoute = `${HttpMethod} /api/${string}`;
const route: ApiRoute = "GET /api/users";          // tur-xavfsiz
// const r2: ApiRoute = "PATCH /api/x";            //  PATCH yo'q

5. To'g'ri va noto'g'ri holatlar

1) Qo'lda takror (utility o'rniga)

ts
//  qo'lda yozish (takror, sinxronsiz)
interface UserUpdate { ism?: string; email?: string; }   // User o'zgarsa — qoladi

//  utility (sinxron — 2.8)
type UserUpdate = Partial<Omit<User, "id">>;

2) Parolni javobda (Omit ishlatmaslik)

ts
//  parol qaytadi (14, 2.9)
function javob(u: User): User { return u; }

//  Omit
function javob(u: User): Omit<User, "parol"> { ... }

3) Ortiqcha tur sehri

ts
//  hech kim tushunmaydigan murakkab tur (2.14)
type X<T> = { [K in keyof T as ...]: T[K] extends ... ? ... };

//  oddiy, o'qiladigan (kerak bo'lsa custom — izoh bilan)

4) any o'rniga conditional/infer

ts
//  any (tur yo'q — 7.1)
function natija(): any {}

//  aniq yoki utility (ReturnType, Awaited — 2.10)

5) Discriminated union'siz murakkab union

ts
//  ajratuvchisiz (narrowing qiyin — 2.2)
type J = { data?: string; xato?: string };

//  discriminated (holat bilan)
type J = { holat: "ok"; data: string } | { holat: "xato"; xabar: string };

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — Type 'X' is not assignable (utility natija)

Sababi: utility natija kutilganidan farq qiladi (Partial — hamma ixtiyoriy). Yechimi: to'g'ri utility tanlang; natijani tekshiring.

Xato 2 — Mapped type sintaksis xatosi

Sababi: [K in keyof T] noto'g'ri 2.5-bob. Yechimi: to'g'ri sintaksis; built-in utility yetsa, uni ishlating.

Xato 3 — Conditional type kutilmagan natija

Sababi: extends shartlari noto'g'ri, distributive 2.6-bob. Yechimi: shartlarni tekshiring; [T] extends [X] (distributive'ni o'chirish).

Xato 4 — infer ishlamaydi

Sababi: infer faqat conditional ichida 2.7-bob. Yechimi: T extends ... infer U ? U : ... to'g'ri tuzilma.

Xato 5 — Tur juda murakkab (o'qib bo'lmaydi)

Sababi: ortiqcha tur sehri 2.14-bob. Yechimi: soddalashtiring; oraliq turlar; izoh; o'qiladigan birinchi.

Xato 6 — Record kaliti yetishmaydi

Sababi: Record hamma kalitni majbur qiladi 2.10-bob. Yechimi: hamma kalit bering; yoki Partial<Record<...>>.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • Turlar 7.2-bob: union/intersection — bu yerda chuqur.
  • Generics 7.3-bob: keyof, conditional — generic bilan.
  • Type guards 7.5-bob: discriminated union narrowing.
  • NestJS 8.5-bob: DTO (Partial/Omit/Pick).
  • Prisma 6.12-bob: generatsiya qilingan turlar.
  • Zod 5.9-bob: infer (schema'dan tur).
  • React 11.10-bob: form turlari, props (utility).
  • Redux (12): action (discriminated union).
  • API DTO: Omit (parolsiz — 14).
  • Kutubxonalar: conditional/mapped (ichki).

8. Eng yaxshi amaliyotlar (best practices)

  • Utility types ishlating (Partial/Pick/Omit/Record — qo'lda yozmang — 2.8-2.10).
  • Bir turdan hosila (DRY, sinxron — DTO oilasi — 2.8, Misol 7).
  • Omit<T, "parol"> — maxfiy yashir (API javob — 14, 2.9).
  • Discriminated union (holat/API javob — narrowing — 2.2).
  • keyof/typeof (turdan tur — 2.3); indexed access (T[K] — 2.4).
  • Custom utility — zarur bo'lganda (mapped + conditional — 2.13).
  • Ortiqcha tur sehridan qoching (o'qiladigan birinchi — 2.14).
  • Template literal — tur-xavfsiz matn (event/route — 2.12).
  • ReturnType/Awaited (funksiya/Promise'dan tur — 2.10).
  • Built-in utility'ni biling (jadval — 2.11).

9. Amaliy loyiha: "Tur Transformatsiyalari Tizimi"

Ilg'or turlarni mustahkamlash.

Maqsad

Bitta domen entity'dan utility types bilan butun DTO/ko'rinish oilasini yaratish va custom utility'lar yasash.

Talablar (requirements)

  1. Domen entity: User/Product (interface — 7.2).
  2. DTO oilasi: Create (Omit), Update (Partial), Response (Omit parol), List (Pick), Login (Pick) — Misol 7, 2.8, 2.9.
  3. Record: rolruxsatlar (Misol 4, 2.10).
  4. Discriminated union: API/fetch holat (Misol 1, 2.2).
  5. keyof/typeof: config tur-xavfsiz (Misol 2, 2.3).
  6. Conditional + infer: Unwrap/NonNull (Misol 5, 2.6, 2.7).
  7. Custom mapped: Nullable, DeepPartial yoki Getters (Misol 6, 2.13).
  8. Template literal: event handler yoki route (Misol 8, 2.12).
  9. Sinxronlik test: entity'ga maydon qo'shing, DTO'lar avtomatik yangilanishini ko'ring 2.8-bob.
  10. O'qiladigan: murakkab tur sehridan qoching 2.14-bob.

Maslahatlar (hint)

  • Omit/Pick/Partial (qo'lda yozma — 2.8, 1-xato).
  • Omit parol (API javob — 14, 2.9).
  • Discriminated: umumiy literal maydon (2.2, 5-xato).
  • infer: conditional ichida (2.7, 4-xato).
  • Record: hamma kalit (2.10, 6-xato).
  • O'qiladigan birinchi (2.14, 3-xato).

"Tayyor" mezonlari (acceptance criteria)

  • Domen entity.
  • DTO oilasi (Create/Update/Response/List/Login).
  • Record (rolruxsat).
  • Discriminated union (holat).
  • keyof/typeof (config).
  • Conditional + infer (custom).
  • Custom mapped type.
  • Template literal type.
  • Sinxronlik (entity o'zgarsa, DTO avtomatik).
  • O'qiladigan (ortiqcha sehir yo'q).

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda TS turlar tizimining eng kuchli qismini o'rgandik:

  • Union/intersection (chuqur — 2.1); discriminated union (ajratuvchi — narrowing — 2.2); keyof/typeof (turdan tur — 2.3); indexed access (T[K] — 2.4).
  • Mapped types ([K in keyof T] — tur o'zgartirish — 2.5); conditional types (extends ? : — 2.6); infer (turni tutish — 2.7).
  • Utility types — Partial/Required 2.8-bob, Pick/Omit 2.9-bob, Record/Readonly/ReturnType/Awaited 2.10-bob; jadval 2.11-bob.
  • Template literal types (matn turlari — 2.12); custom utility 2.13-bob; ortiqcha sehirdan qochish 2.14-bob.

Keyingi bob — 7.5-bob: Type guards, narrowing, type assertions. Turlarni (oddiy va ilg'or) bildik; endi ularni ishlatishda — union turni toraytirish (narrowing): typeof, instanceof, in, custom type guard, va type assertion (as). Bu — TS bilan kundalik ishlashning amaliy qismi (union turni xavfsiz ishlatish).


Foydalanilgan rasmiy/ishonchli manbalar

  • typescriptlang.org — Utility Types; Creating Types from Types (conditional, mapped, infer)
  • TypeScript Handbook — Template Literal Types, keyof, typeof, indexed access
  • DEV/Medium — Advanced TypeScript (conditional, mapped, utility) 2026

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
7.4-bob: Ilg'or turlar — union, intersection, conditional, mapped, utility types — Wisar