WisarWisar
Dasturlash kitobi/7-QISM — TypeScript19 daqiqa

7.5-bob: Type guards, narrowing, type assertions

7-QISM — TypeScript · 5-mavzu


1. Kirish va motivatsiya

Turlarni — oddiy 7.2-bob, generic 7.3-bob, ilg'or 7.4-bob — bildik. Endi ularni ishlatishda muhim ko'nikmani — narrowing (turni toraytirish) — o'rganamiz. Bu — TS bilan kundalik ishlashning amaliy yuragi. Union turlar (string | number, User | null — 7.2) bilan ishlaganda, TS aniq turni bilmaydi (ikkalasidan biri). Ishlatishdan oldin qaysi tur ekanini aniqlash (toraytirish) kerak — bu narrowing.

Eng oddiy misol: string | null turdagi qiymat. .length ni to'g'ridan ishlata olmaysiz (null'da length yo'q — 7.1: 2.10). Avval tekshirasiz (if (x !== null)), va shu blok ichida TS endi xstring ekanini biladi (null emas — toraytirildi). Bu — narrowing. TS juda aqlli: typeof, instanceof, in, tenglik, custom funksiya — bularni tushunib, turni avtomatik toraytiradi (control flow analysis).

Va type assertion (as) — siz TS'ga "men bu turning aniq bilaman" deyish (TS bilmaganda). Bu kuchli, lekin xavfli (TS'ni "aldash" — noto'g'ri bo'lsa runtime xato). Qachon ishlatish/ishlatmaslik muhim. Bu bob: narrowing usullari (typeof, instanceof, in, equality, truthiness), custom type guards (is), discriminated union 7.4-bob, va type assertion (as, !, satisfies) — chuqur. Bu — union turlar bilan xavfsiz ishlashning kaliti.

O'xshatish (narrowing): narrowing — qorong'i xonada chiroqni yoqish. Boshida bilmaysiz — "bu xonada nima bor?" (string | number — ikkisidan biri). Chiroq yoqasiz (typeof x === "string") — endi aniq ko'rasiz ("bu — kitob", ya'ni string). Shu yorug'likda (if blok) xavfsiz ishlaysiz (kitobni o'qiysiz — .length). TS — aqlli: chiroqni qayerda yoqsangiz, o'sha yerda aniq turni biladi.

Nega muhim?

  • Union bilan ishlash — narrowing'siz union turni ishlatib bo'lmaydi.
  • null xavfsizligi — strictNullChecks 7.1-bob narrowing talab qiladi.
  • Kundalik TS — har union/null bilan narrowing (eng ko'p amaliyot).
  • Xavfsizlik — type assertion (as) ni to'g'ri ishlatish (xato oldini olish).

2. Nazariya — chuqur tushuntirish

2.1. Narrowing nima (turni toraytirish)

Narrowing — keng turni (union) torroq, aniq turga keltirish (typescriptlang):

ts
function ishla(x: string | number) {
  // bu yerda x: string | number (keng — aniq emas)
  if (typeof x === "string") {
    // bu yerda x: string (toraytirildi! — TS biladi)
    return x.toUpperCase();        // string metodlari OK
  }
  // bu yerda x: number (qolgani — number)
  return x.toFixed(2);             // number metodlari OK
}

Narrowing mexanizmi (control flow analysis): TS kod oqimini kuzatadi: if (typeof x === "string") blokida x albatta string (TS buni biladi). Bu — TS'ning eng aqlli xususiyati. Tekshirsangiz — TS turni toraytiradi — xavfsiz ishlaysiz.

2.2. typeof narrowing (primitivlar)

ts
function format(x: string | number | boolean) {
  if (typeof x === "string") return x.trim();        // string
  if (typeof x === "number") return x.toFixed(2);    // number
  return x ? "ha" : "yo'q";                          // boolean (qolgani)
}

typeof (2.1-JS) — primitiv turlarni ajratadi: "string", "number", "boolean", "undefined", "object", "function". Eng oddiy narrowing (primitiv union uchun). TS typeof natijasini tushunadi va toraytiradi.

2.3. instanceof narrowing (class'lar)

ts
class Mushuk { miyov() {} }
class It { vov() {} }

function ovoz(hayvon: Mushuk | It) {
  if (hayvon instanceof Mushuk) {
    hayvon.miyov();                 // Mushuk (toraytirildi)
  } else {
    hayvon.vov();                   // It
  }
}

// Xato turlarini ajratish (5.10)
catch (err) {
  if (err instanceof ValidationError) { /* ... */ }   // (5.10)
  if (err instanceof Error) console.log(err.message);
}

instanceof (2.5-JS) — class instansiyalarini ajratadi (x instanceof ClassName). Class union'lar, xato turlari (5.10 — err instanceof Error) uchun. Custom error class'larni 5.10-bob ajratishda muhim.

2.4. in narrowing (obyekt maydonlari)

ts
interface Mushuk { miyov(): void; }
interface It { vov(): void; }

function ovoz(hayvon: Mushuk | It) {
  if ("miyov" in hayvon) {          // "miyov" maydoni bormi?
    hayvon.miyov();                 // Mushuk (toraytirildi)
  } else {
    hayvon.vov();                   // It
  }
}

in (2.8-JS) — obyektda maydon borligini tekshiradi ("x" in obj). Interface union'lar (class emas) uchun (instanceof interface'da ishlamaydi — interface runtime'da yo'q — 7.1: 2.4). Maydon bo'yicha ajratish.

2.5. Equality narrowing (tenglik)

ts
function ishla(x: string | number, y: string | boolean) {
  if (x === y) {                    // ikkalasi teng bo'lsa
    // x va y — IKKALASIDA umumiy tur: string (faqat string teng bo'la oladi)
    x.toUpperCase();                // string
  }
}

// null/undefined tekshirish (eng ko'p — 7.1: 2.10)
function uzunlik(s: string | null) {
  if (s !== null) return s.length;  // null emas  string
  return 0;
}

Equality (===, !==) — tenglik bo'yicha toraytirish. Eng ko'p — null/undefined tekshirish (x !== null — 7.1: 2.10). x === y — umumiy turni topadi. Bu — kundalik narrowing.

2.6. Truthiness narrowing (rost/yolg'on)

ts
function ishla(s: string | null | undefined) {
  if (s) {                          // truthy (null/undefined/"" emas)
    return s.length;                // string (truthy  bor)
  }
  return 0;
}

//  Ehtiyot: "" (bo'sh string), 0 — falsy (2.2-JS)
function tekshir(x: number | null) {
  if (x) { }                        //  0 ham falsy (0 ni o'tkazib yuboradi!)
  if (x !== null) { }               //  aniq null tekshiruvi
}

Truthiness ehtiyot: if (s)null/undefined/""/0/false — hammasi falsy (2.2-JS). number | null da if (x)0 ni ham o'tkazib yuboradi (xato!). Aniq tekshiruv (x !== null) — xavfsizroq. Truthiness — string/obyekt uchun mayli, son/boolean uchun ehtiyot.

2.7. Discriminated union narrowing (7.4 takrori)

ts
type Javob =
  | { holat: "ok"; data: string }
  | { holat: "xato"; xabar: string };

function ishla(j: Javob) {
  switch (j.holat) {                // ajratuvchi (discriminant — 7.4: 2.2)
    case "ok": return j.data;       // { holat: "ok"; data } — data bor
    case "xato": return j.xabar;    // xabar bor
  }
}

Discriminated union (7.4: 2.2) — eng toza narrowing: umumiy literal maydon (holat) bo'yicha switch/if. TS aniq variantni biladi. API javob, Redux action (12), holat — bu naqsh. Eng tavsiya etiladigan union dizayni.

2.8. Custom type guard (is — o'z guard'ing)

Murakkab tekshiruv uchun custom type guardis qaytaradigan funksiya (typescriptlang):

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

// Type guard funksiya (qaytish turi: "x is User")
function isUser(x: unknown): x is User {           // "x is User" — type predicate
  return (
    typeof x === "object" && x !== null &&
    "ism" in x && "email" in x
  );
}

function ishla(data: unknown) {
  if (isUser(data)) {
    data.ism;                       // User (toraytirildi — guard tasdiqladi)
  }
}

Custom type guardfunksiya(x): x is T (type predicate). Funksiya true qaytarsa, TS x — T ekanini biladi (toraytiradi). Murakkab tekshiruv (API javob, unknown — 7.2: 2.3) uchun. unknownni xavfsiz ishlashning asosiy yo'li.

2.9. Assertion functions (assert)

ts
// Assertion function — shart bajarilmasa, xato tashlaydi
function assert(shart: unknown, xabar: string): asserts shart {
  if (!shart) throw new Error(xabar);
}

function isUser2(x: unknown): asserts x is User {
  if (!(typeof x === "object" && x !== null && "ism" in x)) {
    throw new Error("User emas");
  }
}

function ishla(data: unknown) {
  isUser2(data);                    // tasdiqlaydi (yoki xato)
  data.ism;                         // bu yerdan keyin — User (asserts)
}

Assertion function (asserts x is T) — shart bajarilmasa xato tashlaydi; bajarilsa, undan keyin TS turni biladi. assert(shart) — umumiy. Custom guard'dan farqi: guard — if bilan (true/false); assert — xato tashlaydi (davom etmaydi). Validatsiyada 5.9-bob foydali.

2.10. never va exhaustiveness check (to'liqlik)

ts
type Holat = "yangi" | "tasdiqlandi" | "bekor";

function ishla(h: Holat): string {
  switch (h) {
    case "yangi": return "Yangi";
    case "tasdiqlandi": return "Tasdiqlandi";
    case "bekor": return "Bekor";
    default:
      const _exhaustive: never = h;   //  HAMMA holat qoplangan bo'lsa, h: never
      return _exhaustive;             // yangi holat qo'shilsa — KOMPILYATSIYA xatosi!
  }
}

Exhaustiveness check (never bilan) — union'ning hamma varianti qoplanganini kafolatlaydi. defaultda never — agar yangi holat qo'shilsa (lekin case qo'shilmasa), TS xato beradi (neverga assign bo'lmaydi). Bu — union kengayganda xatolarni ushlaydi (juda foydali — switch'larni to'liq tutadi).

2.11. Type assertion (as) — TS'ga "ishonch"

Type assertion (as) — TS'ga "men turni aniq bilaman" deyish (TS bilmaganda):

ts
const el = document.getElementById("input") as HTMLInputElement;   // TS: HTMLElement | null
el.value;                          // HTMLInputElement (as bilan aytdik)

const data = JSON.parse(json) as User;   // JSON.parse  any; biz User deymiz

// Ikki bosqichli (kuch bilan)
const x = (qiymat as unknown) as User;   // (ehtiyot — TS'ni majburlash)

as — xavfli (TS'ni "aldash"): TS turni tekshirmaydi, sizga ishonadi. Noto'g'ri bo'lsa — runtime xato (TS ushlamaydi). Faqat haqiqatan bilganingizda ishlating (DOM element, JSON.parse). Imkon bo'lsa — narrowing/guard (xavfsiz) afzal. as any — eng yomon (qoch).

2.12. Non-null assertion (!)

ts
function ishla(user: User | null) {
  // user.ism;    //  null bo'lishi mumkin (7.1: 2.10)
  user!.ism;      // ! — "null emas" (men bilaman) — TS'ni majburlash
}

const el = document.getElementById("x")!;   // null emas (men bilaman)

Non-null assertion (!) — "bu null/undefined emas" (TS'ni majburlash). asning null versiyasi — xavfli (agar haqiqatan null bo'lsa — crash). Imkon bo'lsa — tekshiruv (if (user)) afzal. ! — faqat aniq bilganda (masalan DOM element bor).

2.13. satisfies operator (zamonaviy — tur tekshiruv + inference)

satisfies — qiymat turga mos ekanini tekshiradi, lekin aniq turni saqlaydi (zamonaviy TS):

ts
// as bilan: aniq tur yo'qoladi
const config1 = { port: 3000, host: "localhost" } as Record<string, string | number>;
// config1.port — string | number (aniq emas)

// satisfies bilan: mos tekshiriladi, LEKIN aniq tur saqlanadi
const config2 = { port: 3000, host: "localhost" } satisfies Record<string, string | number>;
config2.port;     // number (aniq — saqlandi!)
config2.host;     // string (aniq)

satisfiesasning xavfsiz, zamonaviy muqobili: qiymat turga mosligini tekshiradi (xato bo'lsa — kompilyatsiya xatosi), lekin aniq turni (inference) yo'qotmaydi. Config, obyekt literallar uchun a'lo. as (tur aldaydi) o'rniga satisfies (tekshiradi + saqlaydi).

2.14. unknown bilan xavfsiz ishlash (7.2 takrori)

ts
// unknown — har narsa, lekin TEKSHIRISH majbur (any'dan xavfsiz — 7.2: 2.3)
function ishla(data: unknown) {
  // data.foo;            //  "Object is of type 'unknown'"
  if (typeof data === "string") data.toUpperCase();   // narrowing (2.2)
  if (isUser(data)) data.ism;                          // custom guard (2.8)
}

// API javob — unknown, keyin validatsiya (Zod — 5.9)
const javob: unknown = await response.json();
const user = UserSchema.parse(javob);                  // Zod runtime tekshiruv (5.9)

unknownanyning xavfsiz muqobili (7.2: 2.3): har narsani qabul qiladi, lekin ishlatishdan oldin tekshirish majbur (narrowing/guard). API javob, JSON.parse, tashqi ma'lumot — unknown (any emas) + validatsiya (Zod — 5.9). Bu — xavfsiz tur ishlash.

2.15. Best practices (14)

text
   Narrowing (typeof/instanceof/in/equality) — union ishlatishdan oldin (2.1-2.5)
   Discriminated union (eng toza narrowing — 2.7)
   Custom type guard (murakkab/unknown — 2.8)
   Exhaustiveness check (never — union to'liqligi — 2.10)
   as o'rniga narrowing/guard (xavfsiz — 2.11)
   satisfies (as o'rniga — tekshiradi + saqlaydi — 2.13)
   unknown (any o'rniga) + validatsiya (Zod — 2.14, 5.9)
   Truthiness ehtiyot (0/"" — son/boolean'da aniq tekshiring — 2.6)

3. Sintaksis — tez ma'lumotnoma

ts
// Narrowing (2.2-2.6)
if (typeof x === "string") {}        // primitiv
if (x instanceof Class) {}           // class
if ("maydon" in obj) {}              // obyekt maydoni
if (x !== null) {}                   // tenglik/null
if (x) {}                            // truthiness (ehtiyot — 2.6)

// Custom guard 2.8-bob: function isT(x): x is T { return ... }
// Assertion fn 2.9-bob: function assert(c): asserts c {}
// Exhaustiveness 2.10-bob: const _: never = x;

// Assertion (2.11-2.13)
x as Type      // type assertion (xavfli)
x!             // non-null (xavfli)
obj satisfies Type   // tekshir + saqla (zamonaviy)

4. Batafsil kod namunalari

Misol 1 — typeof, instanceof, in (2.2-2.4)

ts
// typeof (primitiv — 2.2)
function format(qiymat: string | number | Date): string {
  if (typeof qiymat === "string") return qiymat.trim();
  if (typeof qiymat === "number") return qiymat.toLocaleString();
  return qiymat.toISOString();          // Date (qolgani)
}

// instanceof (class/xato — 2.3)
function xatoHandle(err: unknown): string {
  if (err instanceof ValidationError) return `Validatsiya: ${err.message}`;   // (5.10)
  if (err instanceof Error) return `Xato: ${err.message}`;
  return "Noma'lum xato";
}

// in (interface union — 2.4)
interface Admin { ruxsatlar: string[]; }
interface User { sotibOlganlar: number; }
function panel(shaxs: Admin | User): string {
  if ("ruxsatlar" in shaxs) return `Admin: ${shaxs.ruxsatlar.length} ruxsat`;
  return `User: ${shaxs.sotibOlganlar} xarid`;
}

Misol 2 — null/undefined narrowing (2.5, 2.6)

ts
// null tekshirish (eng ko'p — 7.1: 2.10)
function salom(ism: string | null | undefined): string {
  if (ism == null) return "Mehmon";    // null VA undefined (== null — ikkalasi)
  return `Salom, ${ism}`;              // string (toraytirildi)
}

// Optional chaining + nullish (2.1-JS)
function shahar(user: { manzil?: { shahar?: string } }): string {
  return user.manzil?.shahar ?? "Noma'lum";   // ?. va ?? (xavfsiz)
}

//  Truthiness ehtiyot (son — 2.6)
function chegirma(foiz: number | null): number {
  if (foiz !== null) return foiz;       //  0 ham o'tadi (aniq null tekshiruvi)
  // if (foiz) ...                       //  0 ni o'tkazib yuboradi!
  return 0;
}

Misol 3 — Discriminated union (2.7)

ts
// API holat (discriminated — 2.7, 7.4: 2.2)
type ApiResult<T> =
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; error: string };

function render<T>(result: ApiResult<T>, formatla: (d: T) => string): string {
  switch (result.status) {
    case "loading": return "Yuklanmoqda...";
    case "success": return formatla(result.data);   // data bor (toraytirildi)
    case "error": return `Xato: ${result.error}`;   // error bor
    default:
      const _: never = result;                       // exhaustiveness (2.10)
      return _;
  }
}

Misol 4 — Custom type guard (2.8)

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

// Type guard (x is User — 2.8)
function isUser(x: unknown): x is User {
  return (
    typeof x === "object" && x !== null &&
    "id" in x && typeof (x as any).id === "number" &&
    "ism" in x && "email" in x
  );
}

// API javob (unknown) ni xavfsiz ishlash
async function userOl(id: number): Promise<User | null> {
  const javob: unknown = await fetch(`/api/users/${id}`).then((r) => r.json());
  if (isUser(javob)) return javob;      // toraytirildi — User
  return null;                          // noto'g'ri shakl
}
//  Production'da Zod 5.9-bob — kuchliroq runtime validatsiya

Misol 5 — Assertion function (2.9)

ts
// Assertion — shart bajarilmasa xato (2.9)
function assertDefined<T>(qiymat: T | null | undefined, xabar: string): asserts qiymat is T {
  if (qiymat == null) throw new Error(xabar);
}

function ishla(user: User | null) {
  assertDefined(user, "User topilmadi");   // null bo'lsa — xato
  return user.ism;                          // bu yerdan keyin — User (asserts)
}

// Umumiy assert
function assert(shart: unknown, xabar: string): asserts shart {
  if (!shart) throw new Error(xabar);
}

Misol 6 — Exhaustiveness check (2.10)

ts
type ToLovUsuli = "naqd" | "karta" | "click" | "payme";

function tolovIcon(usul: ToLovUsuli): string {
  switch (usul) {
    case "naqd": return "";
    case "karta": return "";
    case "click": return "";
    case "payme": return "";
    default:
      // Agar yangi usul ("apelsin") qo'shilsa, lekin case qo'shilmasa 
      // bu yerda usul: never bo'lmaydi  KOMPILYATSIYA xatosi (2.10)
      const _exhaustive: never = usul;
      throw new Error(`Noma'lum usul: ${_exhaustive}`);
  }
}
// Yangi to'lov usuli qo'shilsa, TS bu funksiyani "yangila" deb eslatadi (xavfsiz)

Misol 7 — Type assertion va satisfies (2.11, 2.13)

ts
// as — DOM (TS bilmaydi — 2.11)
const input = document.querySelector("#email") as HTMLInputElement;
input.value;                          // HTMLInputElement (as bilan)

// as — JSON.parse (any  tur)
const config = JSON.parse(raw) as { port: number };   // ehtiyot (tekshirilmaydi!)

//  satisfies — tekshir + aniq tur saqla (2.13)
const ranglar = {
  qizil: "#FF0000",
  yashil: "#00FF00",
} satisfies Record<string, string>;
ranglar.qizil;                        // string (aniq — saqlandi)
// ranglar.kok;                       //  kompilyatsiya xatosi (yo'q kalit)

// satisfies — config/literal uchun (as'dan xavfsiz)
const server = {
  port: 3000,
  host: "localhost",
} satisfies { port: number; host: string };
server.port;                          // number (aniq)

Misol 8 — unknown + Zod (xavfsiz API — 2.14, 5.9)

ts
import { z } from "zod";              // (5.9)

const UserSchema = z.object({
  id: z.number(),
  ism: z.string(),
  email: z.string().email(),
});
type User = z.infer<typeof UserSchema>;   // schema'dan tur (7.4: infer)

// API javob (unknown)  validatsiya  tipli (2.14)
async function userOl(id: number): Promise<User> {
  const javob: unknown = await fetch(`/api/users/${id}`).then((r) => r.json());
  return UserSchema.parse(javob);     // runtime tekshiruv + tur (5.9)
  // parse — noto'g'ri bo'lsa xato tashlaydi; to'g'ri bo'lsa — User (tipli)
}
// unknown (any emas) + Zod = TS (kompilyatsiya) + runtime xavfsizlik

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

1) Union'ni narrowing'siz ishlatish

ts
//  aniq tur emas (xato)
function f(x: string | number) { return x.toUpperCase(); }   // number'da yo'q

//  narrowing
function f(x: string | number) { if (typeof x === "string") return x.toUpperCase(); }

2) as bilan TS'ni aldash

ts
//  as (tekshirilmaydi — runtime xato xavfi — 2.11)
const user = data as User;   // data haqiqatan User emasligi mumkin

//  narrowing/guard yoki Zod
if (isUser(data)) { } // yoki UserSchema.parse(data)

3) Truthiness son/boolean'da

ts
//  0 ni o'tkazib yuboradi (2.6)
if (soni) { }

//  aniq tekshir
if (soni !== null && soni !== undefined) { }

4) any (unknown o'rniga)

ts
//  any (tekshiruv yo'q — 2.14)
function f(data: any) { return data.x; }

//  unknown + narrowing
function f(data: unknown) { if (isT(data)) return data.x; }

5) Exhaustiveness check'siz switch

ts
//  yangi holat qo'shilsa, jim o'tib ketadi (2.10)
switch (h) { case "a": ...; case "b": ...; }

//  never bilan to'liqlik
default: const _: never = h;

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — Property 'x' does not exist on type 'A | B'

Sababi: union'da narrowing yo'q 2.1-bob. Yechimi: typeof/instanceof/in bilan toraytiring.

Xato 2 — Object is possibly 'null'

Sababi: null tekshirilmagan (7.1: 2.10). Yechimi: if (x), x?., x !== null (narrowing).

Xato 3 — as'dan keyin runtime xato

Sababi: as noto'g'ri (TS ishondi, lekin tur boshqa — 2.11). Yechimi: narrowing/guard/Zod (haqiqiy tekshiruv).

Xato 4 — Custom guard ishlamaydi

Sababi: x is T qaytish turi yo'q 2.8-bob. Yechimi: function isT(x): x is T (type predicate).

Xato 5 — Truthiness 0/"" muammosi

Sababi: if (x) falsy qiymatlar 2.6-bob. Yechimi: aniq tekshiruv (!== null).

Xato 6 — Switch'da yangi holat unutildi

Sababi: exhaustiveness check yo'q 2.10-bob. Yechimi: default: const _: never = x.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • Turlar/union 7.2-bob: narrowing — union ishlatish.
  • strictNullChecks 7.1-bob: null narrowing.
  • Ilg'or turlar 7.4-bob: discriminated union.
  • Error handling 5.10-bob: instanceof (xato turlari).
  • Zod 5.9-bob: unknown + runtime validatsiya.
  • API: unknown javob guard/Zod.
  • React (11): props narrowing, discriminated state.
  • Redux (12): action narrowing (discriminated).
  • DOM: as (HTMLInputElement).

8. Eng yaxshi amaliyotlar (best practices)

  • Narrowing (typeof/instanceof/in/equality) — union ishlatishdan oldin (2.1-2.5).
  • Discriminated union (eng toza narrowing — 2.7).
  • Custom type guard (murakkab/unknown — x is T — 2.8).
  • Exhaustiveness check (never — union to'liqligi — 2.10).
  • as o'rniga narrowing/guard/Zod (xavfsiz — 2.11).
  • satisfies (as o'rniga — tekshir + saqla — 2.13).
  • unknown (any o'rniga) + validatsiya (Zod — 2.14, 5.9).
  • Truthiness ehtiyot (son/boolean — aniq tekshiring — 2.6).
  • ! (non-null) faqat aniq bilganda 2.12-bob.
  • null == null (null + undefined birga — Misol 2).

9. Amaliy loyiha: "Type-Safe Ma'lumot Ishlash"

Narrowing va type guard'larni mustahkamlash.

Maqsad

Union turlar, type guard'lar va xavfsiz assertion bilan tur-xavfsiz ma'lumot ishlash tizimini qurish.

Talablar (requirements)

  1. typeof/instanceof/in narrowing: turli union'lar (Misol 1, 2.2-2.4).
  2. null/undefined narrowing: xavfsiz ishlash; truthiness ehtiyot (Misol 2, 2.5, 2.6).
  3. Discriminated union: ApiResult (loading/success/error — Misol 3, 2.7).
  4. Custom type guard: isUser (unknown User — Misol 4, 2.8).
  5. Assertion function: assertDefined (Misol 5, 2.9).
  6. Exhaustiveness check: to'lov usuli switch (never — Misol 6, 2.10).
  7. satisfies: config (as o'rniga — Misol 7, 2.13).
  8. unknown + Zod: API javobni xavfsiz parse (Misol 8, 2.14, 5.9).
  9. as ehtiyot: faqat zarur (DOM) — narrowing afzal 2.11-bob.
  10. strict: any'siz, null xavfsiz 7.1-bob.

Maslahatlar (hint)

  • Union narrowing (typeof/in — 2.1, 1-xato).
  • null: !== null yoki == null (2.5, truthiness ehtiyot — 2.6).
  • Guard: x is T (2.8, 4-xato).
  • Exhaustiveness: const _: never = x 2.10-bob.
  • as o'rniga satisfies/guard (2.11, 2.13).
  • unknown + Zod (2.14, 5.9).

"Tayyor" mezonlari (acceptance criteria)

  • typeof/instanceof/in narrowing.
  • null narrowing (truthiness ehtiyot).
  • Discriminated union (switch).
  • Custom type guard (x is T).
  • Assertion function.
  • Exhaustiveness check (never).
  • satisfies (config).
  • unknown + Zod.
  • as faqat zarur.
  • any'siz, strict.

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


10. Xulosa va keyingi bobga ko'prik

Bu bobda union turlar bilan xavfsiz ishlashni o'rgandik:

  • Narrowing (turni toraytirish — control flow — 2.1): typeof (primitiv — 2.2), instanceof (class — 2.3), in (maydon — 2.4), equality/null 2.5-bob, truthiness (ehtiyot — 2.6).
  • Discriminated union (eng toza — 2.7); custom type guard (x is T — 2.8); assertion function (asserts — 2.9); exhaustiveness (never — 2.10).
  • Type assertion (as — xavfli — 2.11); non-null (! — 2.12); satisfies (zamonaviy — tekshir+saqla — 2.13).
  • unknown (any o'rniga) + validatsiya (Zod — 2.14, 5.9).

Keyingi bob — 7.6-bob: Decorators. Turlar tizimini to'liq bildik; endi TS'ning maxsus xususiyatini — decorators (dekoratorlar) — o'rganamiz. Dekorator — class/metod/xususiyatga "yorliq" qo'shuvchi maxsus sintaksis (@). TypeORM 6.13-bob va NestJS (8) butunlay dekorator asosida — bu bob ularga bevosita tayyorgarlik.


Foydalanilgan rasmiy/ishonchli manbalar

  • typescriptlang.org — Narrowing (typeof, instanceof, in, type predicates, discriminated unions)
  • TypeScript Handbook — Type Guards, assertion functions, never (exhaustiveness)
  • typescriptlang — satisfies operator; unknown vs any

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
7.5-bob: Type guards, narrowing, type assertions — Wisar