4-bo‘lim
Massiv, kortej va obyekt turlari
Kortejlar, readonly, ixtiyoriy maydonlar, indeks imzosi va ortiqcha maydon tekshiruvining kutilmagan qoidasi.
Ushbu bo‘lim mundarijasi
3-bobda massivning asosini ko'rdik. Endi ma'lumot tuzilmalarini aniqroq tasvirlaydigan vositalarga o'tamiz.
Bu bobda ikkita xatti-harakat bor - ular hujjatda yozilgan, lekin duch kelmaguningizcha kutilmagan bo'lib tuyuladi.
Kortej - uzunligi va tartibi qat'iy #
Massivda barcha elementlar bir xil turda. Kortejda esa har bir o'rin o'z turiga ega:
const nuqta: [number, number] = [10, 20];
const juft: [string, number] = ["Olma", 12000];
console.log(nuqta[0] + nuqta[1]);
console.log(juft[0], juft[1]);
tsx src/kortej.ts
30
Olma 12000
Uzunlik ham, tartib ham tekshiriladi:
const nuqta: [number, number] = [10, 20, 30];
const teskari: [string, number] = [12000, "Olma"];
const kam: [string, number] = ["Olma"];
tsc --noEmit 2>&1 | fold -sw 74
src/kortej2.ts(1,7): error TS2322: Type '[number, number, number]' is not
assignable to type '[number, number]'.
Source has 3 element(s) but target allows only 2.
src/kortej2.ts(2,36): error TS2322: Type 'number' is not assignable to
type 'string'.
src/kortej2.ts(2,43): error TS2322: Type 'string' is not assignable to
type 'number'.
src/kortej2.ts(3,7): error TS2322: Type '[string]' is not assignable to
type '[string, number]'.
Source has 1 element(s) but target requires 2.
Uchta xato, uchta boshqa sabab: ortiqcha element, noto'g'ri tartib va yetishmaydigan element.
Nomlangan elementlar #
[number, number] o'qishga noqulay - qaysi biri kenglik?
type Joylashuv = [kenglik: number, uzunlik: number];
const n: Joylashuv = [41.3, 69.2];
console.log(n[0], n[1]);
tsx src/nomli.ts
41.3 69.2
Nomlar faqat hujjat uchun - ular ish vaqtiga ta'sir qilmaydi
va n.kenglik deb yozib bo'lmaydi. Lekin tahrirlovchi maslahatida
va xato xabarlarida ko'rinadi.
Ixtiyoriy va qolgan elementlar #
type Sozlama = [nomi: string, port?: number];
const a: Sozlama = ["dokon"];
const b: Sozlama = ["dokon", 8080];
type Qator = [string, ...number[]];
const q: Qator = ["natijalar", 1, 2, 3];
console.log(a.length, b.length, q.length);
tsx src/ixtiyoriy.ts
1 2 4
| Holat | Mos keladimi |
|---|---|
[x, y] koordinata | Ha |
[xato, natija] qaytish qiymati | Ha |
React useState natijasi | Ha - bu ham kortej |
| Mahsulotlar ro'yxati | Yo'q - oddiy massiv |
| Ikkitadan ko'p tushunarsiz qiymat | Yo'q - obyekt ishlating |
Uch-to'rt elementdan oshsa, [a, b, c, d] ni o'qib bo'lmaydi.
Obyekt esa o'zini tushuntiradi.
readonly massiv #
const sonlar: readonly number[] = [1, 2, 3];
sonlar.push(4);
sonlar[0] = 9;
tsc --noEmit 2>&1 | fold -sw 74
src/readonly.ts(2,8): error TS2339: Property 'push' does not exist on
type 'readonly number[]'.
src/readonly.ts(3,1): error TS2542: Index signature in type 'readonly
number[]' only permits reading.
E'tibor bering: push umuman mavjud emas deb aytilyapti.
readonly number[] - bu boshqa tur, unda o'zgartiruvchi metodlar
yo'q.
const esa massivning o'zini emas, faqat o'zgaruvchini
qotiradi - const sonlar = [1,2] bo'lsa ham sonlar.push(3)
ishlayveradi.
Obyekt turlari #
type Mahsulot = {
nomi: string;
narx: number;
tavsif?: string;
readonly id: number;
};
const m: Mahsulot = { id: 1, nomi: "Olma", narx: 12000 };
console.log(m.nomi, m.tavsif);
tsx src/obyekt.ts
Olma undefined
Uchta belgi:
| Yozuv | Ma'nosi |
|---|---|
nomi: string | Majburiy maydon |
tavsif?: string | Ixtiyoriy - string | undefined |
readonly id: number | Bir marta beriladi, keyin o'zgarmaydi |
readonly ni buzishga urinamiz:
type Mahsulot = { readonly id: number; nomi: string };
const m: Mahsulot = { id: 1, nomi: "Olma" };
m.nomi = "Anor";
m.id = 2;
tsc --noEmit 2>&1 | fold -sw 74
src/readonly2.ts(4,3): error TS2540: Cannot assign to 'id' because it is
a read-only property.
nomi o'zgardi, id esa yo'q.
Ixtiyoriy maydon - undefined bo'lishi mumkin #
type Mahsulot = { nomi: string; tavsif?: string };
const m: Mahsulot = { nomi: "Olma" };
const uzunlik: number = m.tavsif.length;
tsc --noEmit 2>&1 | fold -sw 74
src/ixt2.ts(3,25): error TS18048: 'm.tavsif' is possibly 'undefined'.
Bu strictNullChecks ning ishi. U bo'lmasa, kod jimgina o'tib
ketardi va ish vaqtida yiqilardi.
Tekshirish usullarini 7-bobda ko'ramiz.
Kutilmagan qoida: ortiqcha maydon tekshiruvi #
Bu TypeScript dagi eng ko'p savol tug'diradigan xatti-harakat.
Obyekt literali ortiqcha maydon uchun tekshiriladi:
type Mahsulot = { nomi: string; narx: number };
const m: Mahsulot = { nomi: "Olma", narx: 12000, rang: "qizil" };
tsc --noEmit 2>&1 | fold -sw 74
src/ortiqcha.ts(2,50): error TS2353: Object literal may only specify
known properties, and 'rang' does not exist in type 'Mahsulot'.
Endi aynan o'sha obyekt, lekin o'zgaruvchi orqali:
type Mahsulot = { nomi: string; narx: number };
const xom = { nomi: "Olma", narx: 12000, rang: "qizil" };
const m: Mahsulot = xom;
console.log(m.nomi);
tsc --noEmit && echo "tsc: xato yo'q"
tsx src/ortiqcha2.ts
tsc: xato yo'q
Olma
Xato yo'q. Bir xil ma'lumot, bir xil tur - boshqa natija.
TypeScript tuzilma bo'yicha (structural) ishlaydi: turda talab qilingan maydonlar bo'lsa, qiymat mos keladi. Qo'shimcha maydonlar xalaqit bermaydi.
Lekin literalda ortiqcha maydon deyarli har doim xato -
odatda nom noto'g'ri yozilgan (narx o'rniga narh). Shuning
uchun literal uchun qo'shimcha tekshiruv qo'shilgan.
O'zgaruvchi orqali berilganda esa "bu obyekt boshqa joyda ham ishlatiladi, unda ortiqcha maydon bo'lishi normal" deb hisoblanadi.
Serverdan kelgan obyektni to'g'ridan-to'g'ri turingizga bersangiz, ortiqcha maydonlar jim o'tadi. Kutilmagan maydon borligini bilmay qolasiz.
Muhimi esa bu emas - yetishmaydigan maydon ham tekshirilmaydi,
chunki JSON.parse any qaytaradi. Tashqi ma'lumotni
16-bobdagi usullar bilan tekshiring.
Indeks imzosi #
Kalitlari oldindan noma'lum obyekt uchun:
type Narxlar = { [mahsulot: string]: number };
const n: Narxlar = { olma: 12000, anor: 25000 };
n.uzum = 30000;
console.log(n.olma, n.uzum);
console.log(n.yoq);
tsx src/indeks.ts
12000 30000
undefined
Oxirgi qatorga e'tibor bering: mavjud bo'lmagan kalit
undefined qaytardi - lekin turi number deb aytilgan.
Bu jiddiy xavf:
type Narxlar = { [mahsulot: string]: number };
const n: Narxlar = { olma: 12000 };
const x: number = n.yoq;
console.log(x.toFixed(2));
tsc --noEmit && echo "tsc: xato yo'q"
tsx src/indeks2.ts 2>&1 | grep -oE "TypeError.*" | head -1
tsc: xato yo'q
TypeError: Cannot read properties of undefined (reading 'toFixed')
Kompilyator jim, dastur yiqildi. Yechim - qo'shimcha sozlama:
tsc --noEmit --noUncheckedIndexedAccess 2>&1 | fold -sw 74
src/indeks2.ts(3,7): error TS2322: Type 'number | undefined' is not
assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
noUncheckedIndexedAccess ni yoqingBu sozlama strict ga kirmaydi - uni alohida yoqish kerak:
"noUncheckedIndexedAccess": true
U indeks orqali olingan har bir qiymatga | undefined qo'shadi.
Massiv uchun ham: sonlar[10] endi number | undefined.
Kod biroz ko'proq tekshiruv talab qiladi, lekin aynan shu "bor deb o'ylagan, aslida yo'q" xatolarini yo'qotadi.
Ichma-ich tuzilmalar #
type Buyurtma = {
id: number;
mijoz: { nomi: string; telefon: string };
mahsulotlar: { nomi: string; soni: number }[];
};
const b: Buyurtma = {
id: 1,
mijoz: { nomi: "Husanboy", telefon: "+998901234567" },
mahsulotlar: [
{ nomi: "Olma", soni: 3 },
{ nomi: "Anor", soni: 1 },
],
};
console.log(b.mijoz.nomi, b.mahsulotlar.length);
tsx src/ichki.ts
Husanboy 2
Ichma-ich yozish ishlaydi, lekin tur kattalashgan sari o'qish qiyinlashadi. Amalda uni bo'laklarga ajratish afzal:
type Mijoz = { nomi: string; telefon: string };
type Qator = { nomi: string; soni: number };
type Buyurtma = { id: number; mijoz: Mijoz; mahsulotlar: Qator[] };
Har bir bo'lak alohida nom oladi va boshqa joyda qayta
ishlatiladi. 8-bobda type va interface ni solishtiramiz.
Xulosa #
- Kortej - uzunligi va har bir o'rindagi turi qat'iy massiv:
[number, number]. - Kortejda uzunlik, tartib va yetishmaydigan element - hammasi tekshiriladi.
[kenglik: number, ...]nomlari faqat hujjat uchun; ish vaqtida ular yo'q.- Kortejda ixtiyoriy (
port?) va qolgan (...number[]) elementlar bo'lishi mumkin. readonly number[]- boshqa tur: undapushumuman mavjud emas.constesa faqat o'zgaruvchini qotiradi.- Obyektda
?ixtiyoriy maydonni,readonlyo'zgarmas maydonni belgilaydi. - Ixtiyoriy maydon
undefinedbo'lishi mumkin -strictNullChecksbuni ishlatishdan oldin tekshirishni majbur qiladi. - Ortiqcha maydon faqat obyekt literalida tekshiriladi; o'zgaruvchi orqali berilganda tekshirilmaydi.
- Indeks imzosi mavjud bo'lmagan kalitni ham e'lon qilingan turda ko'rsatadi - bu ish vaqtida yiqilishga olib keladi.
noUncheckedIndexedAccessbuni tuzatadi, lekin ustrictga kirmaydi - alohida yoqish kerak.
[number, number]korteji yarating va unga uchta element berishga urinib ko'ring.- Nomlangan elementli kortej yozing va xato xabarida nomlar ko'rinishini tekshiring.
readonlymassivgapushqilib, xato kodini yozib oling.constmassivgapushqilib, farqni tushuntiring.- Ixtiyoriy va
readonlymaydonli obyekt turi yarating. readonlymaydonni o'zgartirishga urinib ko'ring.- Obyekt literalida ortiqcha maydon yozib,
TS2353ni chaqiring. - O'sha obyektni o'zgaruvchi orqali berib, xato yo'qolishini ko'ring.
- Indeks imzosi bilan mavjud bo'lmagan kalitni o'qing va dasturni yiqiting.
noUncheckedIndexedAccessni yoqib, nechta yangi xato chiqqanini sanang.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.