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 x — string 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):
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)
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). TStypeofnatijasini tushunadi va toraytiradi.
2.3. instanceof narrowing (class'lar)
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)
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 (instanceofinterface'da ishlamaydi — interface runtime'da yo'q — 7.1: 2.4). Maydon bo'yicha ajratish.
2.5. Equality narrowing (tenglik)
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)
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 | nulldaif (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)
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'yichaswitch/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 guard — is qaytaradigan funksiya (typescriptlang):
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 guard —
funksiya(x): x is T(type predicate). Funksiyatrueqaytarsa, TSx— 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)
// 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 —ifbilan (true/false); assert — xato tashlaydi (davom etmaydi). Validatsiyada 5.9-bob foydali.
2.10. never va exhaustiveness check (to'liqlik)
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 (
neverbilan) — union'ning hamma varianti qoplanganini kafolatlaydi.defaultdanever— agar yangi holat qo'shilsa (lekincaseqo'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):
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 (!)
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):
// 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)
satisfies—asning 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'rnigasatisfies(tekshiradi + saqlaydi).
2.14. unknown bilan xavfsiz ishlash (7.2 takrori)
// 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)
unknown—anyning 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)
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
// 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)
// 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)
// 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)
// 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)
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 validatsiyaMisol 5 — Assertion function (2.9)
// 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)
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)
// 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)
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 xavfsizlik5. To'g'ri va noto'g'ri holatlar
1) Union'ni narrowing'siz ishlatish
// 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
// 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
// 0 ni o'tkazib yuboradi (2.6)
if (soni) { }
// aniq tekshir
if (soni !== null && soni !== undefined) { }4) any (unknown o'rniga)
// 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
// 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). aso'rniga narrowing/guard/Zod (xavfsiz — 2.11).satisfies(aso'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)
- typeof/instanceof/in narrowing: turli union'lar (Misol 1, 2.2-2.4).
- null/undefined narrowing: xavfsiz ishlash; truthiness ehtiyot (Misol 2, 2.5, 2.6).
- Discriminated union: ApiResult
(loading/success/error — Misol 3, 2.7). - Custom type guard: isUser (unknown User — Misol 4, 2.8).
- Assertion function: assertDefined (Misol 5, 2.9).
- Exhaustiveness check: to'lov usuli switch (never — Misol 6, 2.10).
- satisfies: config (as o'rniga — Misol 7, 2.13).
- unknown + Zod: API javobni xavfsiz parse (Misol 8, 2.14, 5.9).
- as ehtiyot: faqat zarur (DOM) — narrowing afzal 2.11-bob.
- strict: any'siz, null xavfsiz 7.1-bob.
Maslahatlar (hint)
- Union narrowing (typeof/in — 2.1, 1-xato).
- null:
!== nullyoki== null(2.5, truthiness ehtiyot — 2.6). - Guard:
x is T(2.8, 4-xato). - Exhaustiveness:
const _: never = x2.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!