Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. Union: "bu yoki u"
- 2.1 string | number
- 2.2 Union bilan nima qilish mumkin?
- 2.3 Qiymat berilganda tur o'zi toraydi
- 3. Literal turlar va ularning union'i
- 3.1 Bitta qiymatdan iborat tur
- 3.2 "Faqat shu uch qiymatdan biri"
- 3.3 Son va mantiqiy literallar
- 3.4 Xabarlardagi tartib
- 4. Kengayish: literal qachon string bo'lib qoladi
- 4.1 let va obyekt xususiyati
- 4.2 Uch tuzatish
- 5. Ro'yxat va tur — bitta joyda
- 5.1 Ikki joyda yozish muammosi
- 5.2 as const dan union
- 5.3 includes tuzog'i
- 6. TypeScript nimani ushlamaydi
- 7. Ko'p uchraydigan xatolar
- 7.1 Qo'shtirnoqni unutish
- 7.2 | o'rniga ||
- 7.3 Union'ni let ga berib, keyin kengayishdan hayron bo'lish
- 7.4 typeof X va (typeof X)[number] ni adashtirish
- 8. Mashqlar
- 1-mashq (oson): Turini ayting
- 2-mashq (o'rta): Kengayishni tuzating
- 3-mashq (qiyin): Amaliy tajriba — buyurtma holatlari
- 9. Real ishda
- Xulosa
- Manbalar
TypeScript union va literal turlar: "faol" | "bajarilgan" va as const
Qisqacha: Union (birlashma) — "bu yoki u" turi:
string | number— satr yoki son. Uni literal turlar bilan birlashtirsangiz, qiymat faqat bir nechta aniq variantdan biri bo'ladi:type Filter = "hammasi" | "faol" | "bajarilgan". Imlo xatosi ("bajarlgan") kod ishga tushmasdan ushlanadi. Ro'yxat va turni bir joyda saqlash uchun:const FILTERS = [...] as constvatype Filter = (typeof FILTERS)[number].
Bu darsda
A | Bturini yozasiz va union bilan nima qilish mumkinligini bilasiz.- Satr va son literallaridan "faqat shu variantlar" degan tur yasaysiz.
- Literal tur qachon
stringga kengayishini (widening) va uni qanday to'xtatishni tushuntira olasiz. - Massivdan union yasaysiz: ro'yxat ham, tur ham bitta joyda.
includestuzog'ini va uning to'g'ri yechimini bilasiz.
Oldin bilishingiz kerak: type va interface, Tur annotatsiyasi va tur chiqarish (literal tur), Massiv va tuple turlari (as const).
1. Nega bu kerak?
O'tgan darsda type Size = "kichik" | "o'rta" | "katta" ni ko'rdik va "bu union, keyingi darsda" dedik. Mana o'sha dars.
vazifalar ilovasida filtr bor: "hammasi", "faol", "bajarilgan". Sardor «Bahor» uchun shunga o'xshash buyurtmalar ekranini yozdi:
const orders = [
{ dish: "Osh", done: true },
{ dish: "Manti", done: false },
];
function visible(filter) {
if (filter === "faol") return orders.filter((o) => !o.done);
if (filter === "bajarlgan") return orders.filter((o) => o.done);
return orders;
}
console.log(visible("bajarilgan").length); // 2"Bajarilgan" tugmasi bosilganda ikkala buyurtma ham chiqdi — tayyori ham, tayyor emasi ham. Funksiyada "bajarlgan" deb yozilgan (bitta i tushib qolgan). Satrlar teng emas, shuning uchun kod oxirgi return orders ga yetdi. Xato xabari yo'q.
JavaScript uchun filter — oddiy satr, istalgan satr. Lekin bizning ilovada u faqat uchta qiymatdan biri bo'lishi mumkin. Bu bilim hozir faqat Sardorning boshida. Bugun uni turga yozamiz.
2. Union: "bu yoki u"
2.1 string | number
Union (birlashma) — bir nechta turdan biri bo'la oladigan tur. Ular | ("yoki") bilan yoziladi. Kundalik o'xshatish — kassada to'lov: naqd yoki karta. Ikkalasi ham qabul qilinadi, uchinchisi (masalan, kupon) — yo'q.
let tableId: string | number;
tableId = 7;
tableId = "VIP-2";
console.log(tableId); // VIP-2Stol raqami oddiy zalda son, VIP xonada esa "VIP-2" kabi satr. Ikkalasi ham to'g'ri. true yoki massiv berib bo'lmaydi.
JSDoc darsida union'ni @param {string | number} shaklida ko'rgansiz — yozuv aynan o'sha.
2.2 Union bilan nima qilish mumkin?
Faqat ikkala turda ham bor narsani:
function label(id: string | number) {
return id.toUpperCase();
}Kompilyator:
TS2339: Property 'toUpperCase' does not exist on type 'string | number'.
Property 'toUpperCase' does not exist on type 'number'.Tarjimasi: "string | number turida toUpperCase xususiyati yo'q. Aniqrog'i, number turida yo'q". Ikkinchi qator aybdorni aytadi: union'ning bir a'zosi. id son bo'lsa, toUpperCase yo'q — kod yiqilardi.
Qaysi biri ekanini tekshirsangiz, TypeScript tekshiruvdan keyin turni toraytiradi:
function label(id: string | number) {
if (typeof id === "string") {
return id.toUpperCase();
}
return `Stol ${id}`;
}
console.log(label("vip-2"), label(7)); // VIP-2 Stol 7if ichida id — string, undan keyin esa — number. Bu toraytirish (narrowing); uning hamma usullari — Narrowing: turni toraytirish darsida. Bugun bitta narsani eslab qoling: union qiymatini ishlatishdan oldin, odatda, uning qaysi a'zo ekanini aniqlaysiz.
2.3 Qiymat berilganda tur o'zi toraydi
let tableId: string | number = 7;
console.log(tableId.toFixed(1)); // 7.0tableId — string | number deb e'lon qilingan, lekin TypeScript oxirgi berilgan qiymatni kuzatadi: hozir u 7, son. Shuning uchun toFixed ruxsat. tableId = "VIP-2" dan keyin esa satr bo'ladi. E'lon qilingan tur — "nima bo'lishi mumkin", joriy tur — "hozir nima".
Tekshirib ko'ring:
function len(x: string | string[]) { return x.length; }— xato bormi?
Javob
Xato yo'q. length satrda ham, massivda ham bor — ikkala a'zoning umumiy xususiyati. Union bilan umumiy narsalarni tekshirmasdan ishlatish mumkin. Natija turi ham number — ikkalasida ham length son.
3. Literal turlar va ularning union'i
3.1 Bitta qiymatdan iborat tur
Tur chiqarish darsida literal tur bilan tanishgan edik: const city = "Toshkent" ning turi — "Toshkent", faqat shu satr. Literal turni o'zingiz ham yozishingiz mumkin, lekin bittasi yolg'iz foydasiz: let mode: "tez" ga faqat "tez" beriladi. Kuchi — union'da.
3.2 "Faqat shu uch qiymatdan biri"
type Filter = "hammasi" | "faol" | "bajarilgan";
let current: Filter = "faol";
current = "bajarilgan";
console.log(current); // bajarilganFilter — uchta literal turning union'i: qiymat faqat shu uch satrdan biri. Endi Sardorning xatosi:
type Filter = "hammasi" | "faol" | "bajarilgan";
let current: Filter = "bajarlgan";Kompilyator:
TS2820: Type '"bajarlgan"' is not assignable to type 'Filter'. Did you mean '"bajarilgan"'?Tarjimasi: ""bajarlgan" turini Filter ga berib bo'lmaydi. "bajarilgan" ni nazarda tutdingizmi?" TypeScript nafaqat xatoni topdi, balki to'g'ri variantni ham taklif qildi. Katta-kichik harf ham farq qiladi:
type Filter = "hammasi" | "faol" | "bajarilgan";
function show(filter: Filter) {
return filter;
}
show("Faol");Kompilyator:
TS2345: Argument of type '"Faol"' is not assignable to parameter of type 'Filter'.Muharrirda yana bir foyda bor: show(" deb yozishingiz bilan VS Code uchta variantni ro'yxat qilib taklif qiladi. Variantlarni yodlash shart emas.
3.3 Son va mantiqiy literallar
Literal faqat satr emas:
type Rating = 1 | 2 | 3 | 4 | 5;
const review: Rating = 6;Kompilyator:
TS2322: Type '6' is not assignable to type 'Rating'.TypeScript aytyapti: «6 turini Rating turiga berib bo'lmaydi». Bu yerda 6 — literal tur: faqat 6 sonining o'zi, u esa ruxsat etilgan beshtalikda yo'q.
Mehmon bahosi 1 dan 5 gacha. 6 — xato. Qiziq fakt: boolean turining o'zi ham union — true | false. TypeScript uni hover'da boolean deb qisqa ko'rsatadi.
3.4 Xabarlardagi tartib
Union'da a'zolarning tartibi ahamiyatsiz: "a" | "b" va "b" | "a" — bir xil tur. TypeScript 7 xabarlarda ularni o'z tartibida chiqarishi mumkin. Masalan, "yangi" | "tayyor" | "berildi" xabarda "berildi" | "tayyor" | "yangi" bo'lib ko'rinadi. Hayron bo'lmang — tur o'sha.
Tekshirib ko'ring:
type Size = "kichik" | "o'rta" | "katta";vaconst s: Size = "O'rta";— xato bormi? Nega?
Javob
Xato bor — TS2322. Literal tur aynan bitta satr: "o'rta" va "O'rta" — boshqa-boshqa satrlar (birinchi harf katta). TypeScript JavaScript'dagi === kabi solishtiradi: harfma-harf.
4. Kengayish: literal qachon string bo'lib qoladi
4.1 let va obyekt xususiyati
Tur chiqarish darsidagi qoida endi amalda kerak bo'ladi: let va obyekt ichidagi literal kengayadi (widening) — "faol" → string.
type Status = "yangi" | "tayyor";
function setStatus(status: Status) {
return status;
}
const order = { dish: "Osh", status: "yangi" };
setStatus(order.status);Kompilyator:
TS2345: Argument of type 'string' is not assignable to parameter of type 'Status'.Qiymat — aynan "yangi", xabar esa string deydi. Nega? Obyekt xususiyatini keyin o'zgartirish mumkin (order.status = "boshqa"), shuning uchun TypeScript status ga keng tur berdi: string. string esa Status ga mos emas — har satr ham holat emas.
4.2 Uch tuzatish
type Status = "yangi" | "tayyor";
function setStatus(status: Status) {
return status;
}
// 1) obyektga tur yozish
const a: { dish: string; status: Status } = {
dish: "Osh",
status: "yangi",
};
// 2) faqat bitta qiymatni "qotirish"
const b = { dish: "Manti", status: "yangi" as const };
// 3) butun obyektni qotirish (hammasi readonly bo'ladi)
const c = { dish: "Lag'mon", status: "tayyor" } as const;
console.log(setStatus(a.status), setStatus(b.status)); // yangi yangi
console.log(setStatus(c.status)); // tayyortsc --declaration bilan uchala o'zgaruvchining turini ko'rdik (muharrir hover'da xuddi shuni ko'rsatadi):
| Kod | Chiqarilgan tur |
|---|---|
{ dish: "Osh", status: "yangi" } |
{ dish: string; status: string; } |
{ …, status: "yangi" as const } |
{ dish: string; status: "yangi"; } |
{ … } as const |
{ readonly dish: "Lag'mon"; readonly status: "tayyor"; } |
Qaysi birini tanlash? Obyekt keyin o'zgaradigan bo'lsa (buyurtma holati "yangi" dan "tayyor" ga o'tadi) — birinchisi: tur yozish. Butunlay o'zgarmas sozlama bo'lsa — uchinchisi. as const ni massivlarda ko'rgan edik — obyektda ham xuddi shu ish qiladi: literal turlar va readonly.
flowchart TD
A["Literal qiymat: "faol""] --> B{"Qayerda yozilgan?"}
B -- "const x = …" --> L["Literal tur: "faol""]
B -- "let x = …" --> S["Kengayadi: string"]
B -- "obyekt yoki massiv ichida" --> S
B -- "… as const" --> R["Literal + readonly"]
B -- "tur yozilgan: x: Filter" --> F["Filter"]Sxema bitta savol beradi: "qiymat keyin o'zgarishi mumkinmi?" Mumkin bo'lsa — TypeScript kengaytiradi. Siz aniq tur yozsangiz yoki as const desangiz — kengaytirmaydi.
Tekshirib ko'ring:
let mode = "faol"; show(mode);(show(filter: Filter)) — xato bormi?letniconstga almashtirsak-chi?
Javob
let bilan — TS2345: Argument of type 'string' is not assignable to parameter of type 'Filter'. — let mode kengaydi. const bilan — xato yo'q: const mode turi "faol", u Filter ning a'zosi. Uchinchi yo'l: let mode: Filter = "faol"; — let ham qoladi, tur ham aniq.
5. Ro'yxat va tur — bitta joyda
5.1 Ikki joyda yozish muammosi
Ko'pincha union'ning qiymatlari ishlash paytida ham kerak: tugmalar chizish, URL'dagi qiymatni tekshirish. Sodda yo'l — ikki marta yozish:
type Filter = "hammasi" | "faol" | "bajarilgan";
const FILTERS = ["hammasi", "faol", "bajarilgan"];Ertaga "arxiv" filtri qo'shiladi. Uni bir joyga yozib, ikkinchisini unutish oson. Tur va ro'yxat bir-biridan ajraladi.
5.2 as const dan union
Teskari yo'ldan boramiz: ro'yxatni bir marta yozamiz, turni undan chiqaramiz:
const FILTERS = ["hammasi", "faol", "bajarilgan"] as const;
type Filter = (typeof FILTERS)[number];
const first: Filter = FILTERS[0];
console.log(FILTERS.length, first); // 3 hammasiBosqichma-bosqich o'qiymiz:
as const— massiv o'zgarmas tuple bo'ldi:readonly ["hammasi", "faol", "bajarilgan"](o'tgan darslardan).typeof FILTERS— tur joyida yozilgantypeof: "FILTERSo'zgaruvchisining turi". Bu JavaScript'dagitypeofemas (u satr qaytaradi). Tur joyida u TypeScript'ning operatori.[number]— "shu turdagi massivning istalgan raqamli indeksidagi element turi". Tuple'da bu — hamma elementlar turlarining union'i.
Natija: Filter = "hammasi" | "faol" | "bajarilgan". Endi "arxiv" ni faqat FILTERS ga qo'shasiz — tur o'zi yangilanadi. typeof va indeks bilan tur olishning hamma imkoniyatlari — keyof, typeof va indexed access darsida.
5.3 includes tuzog'i
URL'dan kelgan matn — oddiy string. Uni ro'yxatda bormi deb tekshiramiz:
const FILTERS = ["hammasi", "faol", "bajarilgan"] as const;
type Filter = (typeof FILTERS)[number];
function parseFilter(text: string): Filter {
if (FILTERS.includes(text)) {
return text;
}
return "hammasi";
}Kompilyator:
TS2345: Argument of type 'string' is not assignable to parameter of type '"bajarilgan" | "faol" | "hammasi"'.
TS2322: Type 'string' is not assignable to type '"bajarilgan" | "faol" | "hammasi"'.TypeScript aytyapti: «string turidagi argumentni "bajarilgan" | "faol" | "hammasi" turidagi parametrga berib bo'lmaydi» va «string ni o'sha uchtalikka yozib bo'lmaydi». Ya'ni har qanday satr emas, faqat shu uch so'z kerak.
Ikki xato, ikkalasi ham kutilmagan:
includeso'z massivining element turini kutadi.FILTERS—Filterlar massivi, shuning uchunincludesham faqatFilterqabul qiladi. Bizda esastring. TypeScript'ning mantig'i: "satrlar massivida yo'q narsani qidirish — xato bo'lishi mumkin".includestoraytirmaydi.trueqaytgan bo'lsa ham,textstringbo'lib qoladi vaFiltersifatida qaytarib bo'lmaydi.
To'g'ri yo'l — find. U topilgan elementni qaytaradi, element turi esa — Filter:
const FILTERS = ["hammasi", "faol", "bajarilgan"] as const;
type Filter = (typeof FILTERS)[number];
function parseFilter(text: string | null): Filter {
return FILTERS.find((filter) => filter === text) ?? "hammasi";
}
console.log(parseFilter("faol")); // faol
console.log(parseFilter("bajarlgan")); // hammasi
console.log(parseFilter(null)); // hammasifind — Filter | undefined qaytaradi: topilsa — ro'yxatdagi qiymat (aynan Filter turida), topilmasa — undefined. ?? esa undefined o'rniga standart filtrni qo'yadi. Parametr — string | null: brauzerdagi URLSearchParams.get() parametr yo'q bo'lsa null qaytaradi. Qiymat va tur bir vaqtda tekshirildi. vazifalar ning marshrut moduli null va undefined bilan xavfsiz ishlash qadamida aynan shu usulga o'tadi.
Tekshirib ko'ring:
const SIZES = ["kichik", "katta"] as const; type Size = typeof SIZES;—const s: Size = "kichik"ishlaydimi?
Javob
Yo'q: TS2322: Type 'string' is not assignable to type 'readonly ["kichik", "katta"]'. typeof SIZES — massivning o'zi (tuple) turi, uning elementi emas. Element turi uchun oxiriga [number] qo'shiladi: type Size = (typeof SIZES)[number];.
6. TypeScript nimani ushlamaydi
Union — kompilyatsiya paytidagi va'da. Tashqaridan kelgan matn bu va'dani bilmaydi:
type Filter = "hammasi" | "faol" | "bajarilgan";
const TITLES = {
hammasi: "Hammasi",
faol: "Faol",
bajarilgan: "Bajarilgan",
};
const saved: Filter = JSON.parse('"arxiv"'); // eski versiyadan
console.log(TITLES[saved].toUpperCase());tsc — xatosiz: JSON.parse — any, u Filter ga jim mos keladi. TITLES[saved] ning turi — string (uchala kalit ham bor). Node esa:
TypeError: Cannot read properties of undefined (reading 'toUpperCase')localStorage dagi eski qiymat "arxiv" ilovaning yangi versiyasida yo'q. Tashqi qiymatni union'ga berishdan oldin tekshiring: yuqoridagi parseFilter aynan shuni qiladi. Server ma'lumotlarini tekshirish — API ma'lumotlarini tiplash darsida.
7. Ko'p uchraydigan xatolar
7.1 Qo'shtirnoqni unutish
type Size = kichik | katta;Kompilyator:
TS2304: Cannot find name 'kichik'.
TS2304: Cannot find name 'katta'.Tarjimasi: "kichik nomini topib bo'lmadi". Qo'shtirnoqsiz kichik — tur nomi deb o'qiladi (MenuItem kabi), bunday tur esa yo'q. Tuzatish: type Size = "kichik" | "katta";.
7.2 | o'rniga ||
|| — JavaScript'ning "yoki" operatori, qiymatlar bilan ishlaydi. Turlarda — bitta |. Tuzatish: string | number.
7.3 Union'ni let ga berib, keyin kengayishdan hayron bo'lish
let filter = "faol" — string. Tuzatish: const yoki aniq tur: let filter: Filter = "faol".
7.4 typeof X va (typeof X)[number] ni adashtirish
Birinchisi — butun massiv turi, ikkinchisi — element turi. Tuzatish: union kerak bo'lsa — [number] bilan.
8. Mashqlar
1-mashq (oson): Turini ayting
const PORTIONS = ["yarim", "to'liq"] as const;
type Portion = (typeof PORTIONS)[number];
let spice = "achchiq";
const level = 2;
const p: Portion = "yarim";
console.log(PORTIONS.length, spice, level, p); // 2 achchiq 2 yarimlet spice ning turi: [:string]. const level ning turi (literal): [:2]. Portion nechta a'zodan iborat: .
Yechim
spice — let, literal kengaydi: string. level — const, turi aynan 2. Portion — "yarim" | "to'liq", ikki a'zo: as const massivi elementlaridan yasalgan union.
2-mashq (o'rta): Kengayishni tuzating
Kod tsc dan o'tmaydi. Ikki xil yo'l bilan tuzating: (a) obyektga tur yozib, (b) as const bilan. Qaysi biri bu yerda to'g'riroq?
type Payment = "naqd" | "karta" | "click";
function pay(sum: number, method: Payment) {
return `${sum} so'm — ${method}`;
}
const bill = { sum: 70000, method: "karta" };
bill.method = "naqd";
console.log(pay(bill.sum, bill.method));Kompilyator:
TS2345: Argument of type 'string' is not assignable to parameter of type 'Payment'.Yechim
(a) — to'g'ri yo'l, chunki bill.method keyin o'zgaradi:
type Payment = "naqd" | "karta" | "click";
function pay(sum: number, method: Payment) {
return `${sum} so'm — ${method}`;
}
const bill: { sum: number; method: Payment } = {
sum: 70000,
method: "karta",
};
bill.method = "naqd";
console.log(pay(bill.sum, bill.method)); // 70000 so'm — naqd(b) as const bilan esa ikkinchi qator buziladi:
type Payment = "naqd" | "karta" | "click";
const bill = { sum: 70000, method: "karta" } as const;
bill.method = "naqd";Kompilyator:
TS2540: Cannot assign to 'method' because it is a read-only property.as const hammasini readonly qiladi — o'zgarmaydigan qiymatlar uchun. { method: "karta" as const } (faqat bitta qiymat) ham yordam bermaydi: unda method turi aynan "karta" bo'ladi va "naqd" ni yozib bo'lmaydi (TS2322). Qiymat o'zgaradigan bo'lsa — union'ni tur sifatida yozing.
3-mashq (qiyin): Amaliy tajriba — buyurtma holatlari
Mashq kurs/mashqlar/15/ papkasida. 07-union/order-status.ts faylini yarating. Birinchi variant JavaScript'dan "to'g'ridan-to'g'ri" ko'chirilgan:
// 07-union/order-status.ts — «Bahor» buyurtma holatlari
export const STATUSES = [
"yangi",
"tayyorlanmoqda",
"tayyor",
"berildi",
] as const;
export type OrderStatus = (typeof STATUSES)[number];
const LABELS = {
yangi: "Yangi buyurtma",
tayyorlanmoqda: "Oshxonada",
tayyor: "Olib keting",
};
export function parseStatus(text: string): OrderStatus {
if (STATUSES.includes(text)) {
return text;
}
throw new RangeError(`Noma'lum holat: ${text}`);
}
export function statusLabel(status: OrderStatus): string {
return LABELS[status];
}npx tsc --pretty falseni ishga tushiring — uchta xato chiqadi. Har birini o'qing: qaysi biri «includestuzog'i», qaysi biri yangi?- Uchala xatoni tuzating.
parseStatusbegona matndaRangeErrortashlasin. nextStatus(status)qo'shing: keyingi holat, oxirgisidan keyin — o'zi. Ishora:STATUSES.indexOf(status) + 1— keyingi indeks. Mashqlar papkasidanoUncheckedIndexedAccessyoqilgan — indeks natijasiOrderStatus | undefined, uni??bilan yoping.07-union/order-status.test.tsda testlar yozing: to'g'ri va begona matn (katta harfli ham), holatlar zanjiri, har holatning yozuvi borligi.
Yechim
1-qadamda tsc 7.0.2 shunday dedi:
07-union/order-status.ts(17,25): error TS2345: Argument of type 'string' is not assignable to parameter of type '"berildi" | "tayyor" | "tayyorlanmoqda" | "yangi"'.
07-union/order-status.ts(18,5): error TS2322: Type 'string' is not assignable to type '"berildi" | "tayyor" | "tayyorlanmoqda" | "yangi"'.
07-union/order-status.ts(24,10): error TS7053: Element implicitly has an 'any' type because expression of type '"berildi" | "tayyor" | "tayyorlanmoqda" | "yangi"' can't be used to index type '{ yangi: string; tayyorlanmoqda: string; tayyor: string; }'.
Property 'berildi' does not exist on type '{ yangi: string; tayyorlanmoqda: string; tayyor: string; }'.Birinchi ikkitasi — «includes tuzog'i». Uchinchisi yangi va juda foydali: "berildi xususiyati LABELS da yo'q". LABELS[status] — status to'rt qiymatdan biri, LABELS da esa faqat uchta kalit. JavaScript'da "berildi" holatidagi buyurtma ekranda undefined yozuvi bilan chiqardi. Union ro'yxat va yozuvlar jadvalini bir-biriga bog'ladi: yangi holat qo'shilsa, tsc yozuvi yo'qligini darhol aytadi. (TS7053 va Record bilan bunday jadvallarni yozish — Index signature va Record darsida.)
// 07-union/order-status.ts — «Bahor» buyurtma holatlari
export const STATUSES = [
"yangi",
"tayyorlanmoqda",
"tayyor",
"berildi",
] as const;
export type OrderStatus = (typeof STATUSES)[number];
const LABELS = {
yangi: "Yangi buyurtma",
tayyorlanmoqda: "Oshxonada",
tayyor: "Olib keting",
berildi: "Berildi",
};
// Tashqaridan kelgan matn — oq ro'yxatdan; find topganini
// OrderStatus turida qaytaradi, topmasa — undefined
export function parseStatus(text: string): OrderStatus {
const found = STATUSES.find((status) => status === text);
if (found === undefined) {
throw new RangeError(`Noma'lum holat: ${text}`);
}
return found;
}
// Keyingi holat; oxirgisidan keyin — o'zi
export function nextStatus(status: OrderStatus): OrderStatus {
const next = STATUSES[STATUSES.indexOf(status) + 1];
return next ?? status;
}
export function statusLabel(status: OrderStatus): string {
return LABELS[status];
}if (found === undefined) dan keyin found — OrderStatus: undefined chiqarib tashlandi. nextStatus da "berildi" ning indeksi 3, STATUSES[4] — undefined, demak holat o'zgarmaydi.
// 07-union/order-status.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import {
STATUSES,
parseStatus,
nextStatus,
statusLabel,
} from "./order-status.ts";
test("parseStatus: ro'yxatdagi matn", () => {
assert.equal(parseStatus("tayyor"), "tayyor");
});
test("parseStatus: begona va katta harfli matn — RangeError", () => {
assert.throws(() => parseStatus("bekor"), RangeError);
assert.throws(() => parseStatus("Tayyor"), RangeError);
});
test("nextStatus: zanjir va oxirgi holat", () => {
assert.equal(nextStatus("yangi"), "tayyorlanmoqda");
assert.equal(nextStatus("tayyor"), "berildi");
assert.equal(nextStatus("berildi"), "berildi");
});
test("statusLabel: har holatning yozuvi bor", () => {
for (const status of STATUSES) {
assert.notEqual(statusLabel(status), undefined);
}
assert.equal(statusLabel("tayyor"), "Olib keting");
});Testda nextStatus("bekor") deb yozib ko'ring — tsc TS2345 beradi: testlar ham turlar bilan tekshiriladi. npx tsc --pretty false — chiqishsiz. node --test 07-union/order-status.test.ts — bizda (Node 24.21.0):
✔ parseStatus: ro'yxatdagi matn (1.8442ms)
✔ parseStatus: begona va katta harfli matn — RangeError (0.9695ms)
✔ nextStatus: zanjir va oxirgi holat (0.2975ms)
✔ statusLabel: har holatning yozuvi bor (0.391ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 259.1104XATOLAR.md ga yangi xabarlarni qo'shing: TS2820, TS2304, TS7053. Keyin kurs/mashqlar papkasidan:
git add 15/07-union 15/XATOLAR.md
git commit -m "15/07: order-status.ts — literal union, as const, find"Oldinga qarab: Vazifalar qadami. vazifalar da hali hamma filtr, saralash va xato kodlari oddiy string. Ruxsat etilgan qiymatlar faqat izohda yozilgan: @param {string} filtr "hammasi" | "faol" | "bajarilgan". Discriminated union va to'liqlik tekshiruvi qadamida turlar.ts ga Filtr, Saralash, TarmoqHolati va ikki xato kodi turi union bo'lib qo'shiladi, izohdagi ro'yxatlar esa turga aylanadi.
9. Real ishda
- Holatlar va rejimlar — union'ning eng ko'p joyi: so'rov holati
"idle" | "loading" | "error", tugma ko'rinishi"primary" | "danger", HTTP metodi"GET" | "POST". Kutubxonalarning turlari ham shunday:fetchningRequestInitidagimode—"cors" | "no-cors" | "navigate" | "same-origin". - Komponent xususiyatlari (React, 17-qismdan) —
size: "sm" | "md" | "lg". Noto'g'ri qiymat bilan komponentni ishlatsangiz, muharrir darhol qizil chiziq tortadi. as constro'yxatlar — ruxsat etilgan qiymatlarning "yagona manbai": undan ham tur, ham<select>variantlari, ham tekshiruv yasaladi.- Intervyu: "Union va literal turlar nima?", "Nega
let x = "a"ning turistring?", "as constnima qiladi?" — odatiy savollar.
Xulosa
A | B— "bu yoki u". Union bilan faqat umumiy narsalarni tekshirmasdan ishlatish mumkin, qolganiga — toraytirish.- Literal turlar union'i — "faqat shu variantlar":
"hammasi" | "faol" | "bajarilgan". Imlo (TS2820) va katta-kichik harf xatolari ushlanadi. letva obyekt ichidagi literalstringga kengayadi. To'xtatish: tur yozish (o'zgaradigan qiymat) yokias const(o'zgarmas).- Ro'yxat va tur bir joyda:
const X = [...] as const; type T = (typeof X)[number];. includessatrni toraytirmaydi vastringni qabul qilmaydi —find(...) ?? standartishlating.
Keyingi dars: any, unknown, never, void va object — "hamma narsa", "noma'lum", "hech qachon" va "hech narsa qaytarmaydi" degan maxsus turlar.
Manbalar
- TypeScript Handbook: "Everyday Types" → Union Types, Literal Types, Literal Inference — typescriptlang.org/docs/handbook/2/everyday-types.html#union-types
- TypeScript Handbook: "Typeof Type Operator", "Indexed Access Types" — typescriptlang.org/docs/handbook/2/typeof-types.html
- TypeScript Release Notes 3.4 (
constassertions) — typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html - MDN:
URLSearchParams.get()— developer.mozilla.org/docs/Web/API/URLSearchParams/get
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!