4-bo‘lim

Massiv, kortej va obyekt turlari

Kortejlar, readonly, ixtiyoriy maydonlar, indeks imzosi va ortiqcha maydon tekshiruvining kutilmagan qoidasi.

🕑 23 daqiqa o‘qish 📄 774 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Kortej - uzunligi va tartibi qat'iy
  2. Nomlangan elementlar
  3. Ixtiyoriy va qolgan elementlar
  4. readonly massiv
  5. Obyekt turlari
  6. Ixtiyoriy maydon - undefined bo'lishi mumkin
  7. Kutilmagan qoida: ortiqcha maydon tekshiruvi
  8. Indeks imzosi
  9. Ichma-ich tuzilmalar
  10. Xulosa

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:

TS
const nuqta: [number, number] = [10, 20];
const juft: [string, number] = ["Olma", 12000];

console.log(nuqta[0] + nuqta[1]);
console.log(juft[0], juft[1]);
Terminal
tsx src/kortej.ts
Natija
30
Olma 12000

Uzunlik ham, tartib ham tekshiriladi:

TS
const nuqta: [number, number] = [10, 20, 30];
const teskari: [string, number] = [12000, "Olma"];
const kam: [string, number] = ["Olma"];
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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?

TS
type Joylashuv = [kenglik: number, uzunlik: number];
const n: Joylashuv = [41.3, 69.2];
console.log(n[0], n[1]);
Terminal
tsx src/nomli.ts
Natija
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 #

TS
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);
Terminal
tsx src/ixtiyoriy.ts
Natija
1 2 4
Kortej qachon kerak?
HolatMos keladimi
[x, y] koordinataHa
[xato, natija] qaytish qiymatiHa
React useState natijasiHa - bu ham kortej
Mahsulotlar ro'yxatiYo'q - oddiy massiv
Ikkitadan ko'p tushunarsiz qiymatYo'q - obyekt ishlating

Uch-to'rt elementdan oshsa, [a, b, c, d] ni o'qib bo'lmaydi. Obyekt esa o'zini tushuntiradi.

readonly massiv #

TS
const sonlar: readonly number[] = [1, 2, 3];
sonlar.push(4);
sonlar[0] = 9;
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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 #

TS
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);
Terminal
tsx src/obyekt.ts
Natija
Olma undefined

Uchta belgi:

YozuvMa'nosi
nomi: stringMajburiy maydon
tavsif?: stringIxtiyoriy - string | undefined
readonly id: numberBir marta beriladi, keyin o'zgarmaydi

readonly ni buzishga urinamiz:

TS
type Mahsulot = { readonly id: number; nomi: string };
const m: Mahsulot = { id: 1, nomi: "Olma" };
m.nomi = "Anor";
m.id = 2;
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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 #

TS
type Mahsulot = { nomi: string; tavsif?: string };
const m: Mahsulot = { nomi: "Olma" };
const uzunlik: number = m.tavsif.length;
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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:

TS
type Mahsulot = { nomi: string; narx: number };
const m: Mahsulot = { nomi: "Olma", narx: 12000, rang: "qizil" };
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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:

TS
type Mahsulot = { nomi: string; narx: number };
const xom = { nomi: "Olma", narx: 12000, rang: "qizil" };
const m: Mahsulot = xom;
console.log(m.nomi);
Terminal
tsc --noEmit && echo "tsc: xato yo'q"
tsx src/ortiqcha2.ts
Natija
tsc: xato yo'q
Olma

Xato yo'q. Bir xil ma'lumot, bir xil tur - boshqa natija.

Ortiqcha maydon qachon tekshiriladi? To'g'ridan-to'g'ri literal const m: Mahsulot = { nomi, narx, rang }; Tekshiriladi TS2353 xatosi "rang bunday turda yo'q" O'zgaruvchi orqali const xom = { ..., rang }; const m: Mahsulot = xom; Tekshirilmaydi Xato yo'q "kerakli maydonlar bor - yetarli" Sabab: TypeScript tuzilma bo'yicha ishlaydi - kerakli maydonlar bo'lsa, tur mos keladi. Literal uchun esa qo'shimcha tekshiruv bor: "bu maydonni ataylab yozdingizmi?"
Literal uchun qo'shimcha tekshiruv, o'zgaruvchi uchun yo'q
Nima uchun shunday?

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.

Bu tuzoq API bilan ishlaganda uchraydi

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:

TS
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);
Terminal
tsx src/indeks.ts
Natija
12000 30000
undefined

Oxirgi qatorga e'tibor bering: mavjud bo'lmagan kalit undefined qaytardi - lekin turi number deb aytilgan.

Bu jiddiy xavf:

TS
type Narxlar = { [mahsulot: string]: number };
const n: Narxlar = { olma: 12000 };
const x: number = n.yoq;
console.log(x.toFixed(2));
Terminal
tsc --noEmit && echo "tsc: xato yo'q"
tsx src/indeks2.ts 2>&1 | grep -oE "TypeError.*" | head -1
Natija
tsc: xato yo'q
TypeError: Cannot read properties of undefined (reading 'toFixed')

Kompilyator jim, dastur yiqildi. Yechim - qo'shimcha sozlama:

Terminal
tsc --noEmit --noUncheckedIndexedAccess 2>&1 | fold -sw 74
Natija
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 yoqing

Bu sozlama strict ga kirmaydi - uni alohida yoqish kerak:

Natija
"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 #

TS
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);
Terminal
tsx src/ichki.ts
Natija
Husanboy 2

Ichma-ich yozish ishlaydi, lekin tur kattalashgan sari o'qish qiyinlashadi. Amalda uni bo'laklarga ajratish afzal:

Natija
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: unda push umuman mavjud emas. const esa faqat o'zgaruvchini qotiradi.
  • Obyektda ? ixtiyoriy maydonni, readonly o'zgarmas maydonni belgilaydi.
  • Ixtiyoriy maydon undefined bo'lishi mumkin - strictNullChecks buni 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.
  • noUncheckedIndexedAccess buni tuzatadi, lekin u strict ga kirmaydi - alohida yoqish kerak.
Amaliy topshiriq
  1. [number, number] korteji yarating va unga uchta element berishga urinib ko'ring.
  2. Nomlangan elementli kortej yozing va xato xabarida nomlar ko'rinishini tekshiring.
  3. readonly massivga push qilib, xato kodini yozib oling.
  4. const massivga push qilib, farqni tushuntiring.
  5. Ixtiyoriy va readonly maydonli obyekt turi yarating.
  6. readonly maydonni o'zgartirishga urinib ko'ring.
  7. Obyekt literalida ortiqcha maydon yozib, TS2353 ni chaqiring.
  8. O'sha obyektni o'zgaruvchi orqali berib, xato yo'qolishini ko'ring.
  9. Indeks imzosi bilan mavjud bo'lmagan kalitni o'qing va dasturni yiqiting.
  10. noUncheckedIndexedAccess ni yoqib, nechta yangi xato chiqqanini sanang.

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.