Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. Shakl bo'yicha moslik
- 2.1 Savol: "kerakli xususiyatlar bormi?"
- 2.2 Bir xil shakl — bir xil tur
- 2.3 Ko'proq — mos, kamroq — yo'q
- 3. Xususiyatlar turlari ham solishtiriladi
- 3.1 Har xususiyat — alohida
- 3.2 Ixtiyoriy va majburiy
- 3.3 Massivlar va funksiyalar
- 4. Ortiqcha xususiyat tekshiruvi bilan farqi
- 5. Klasslar ham shakl bo'yicha
- 5.1 Klass turi — uning ochiq xususiyatlari
- 5.2 Yopiq # maydon shaklni "noyob" qiladi
- 5.3 vazifalar da: Vazifa va Saralanadigan
- 6. TypeScript nimani ushlamaydi: nominal emaslik
- 7. Ko'p uchraydigan xatolar
- 7.1 Parametrga klass turini yozish
- 7.2 "Turini e'lon qilmagan — demak mos emas" deb o'ylash
- 7.3 Tur nomi himoya qiladi deb o'ylash
- 7.4 instanceof ga ishonish
- 8. Mashqlar
- 1-mashq (oson): Mos keladimi?
- 2-mashq (o'rta): Nega cookMinutes yo'qoldi?
- 3-mashq (qiyin): Amaliy tajriba — menyu taxtasi
- 9. Real ishda
- Xulosa
- Manbalar
TypeScript strukturaviy tiplash: tur nomi emas, shakli muhim
Qisqacha: TypeScript'da ikki tur nomi bilan emas, shakli bilan solishtiriladi: kerakli xususiyatlari bor har qanday obyekt turga mos keladi. Bu strukturaviy tiplash (structural typing).
{ name: string; price: number }kutilgan joygaDishklassi obyektini ham, ortiqcha xususiyatli oddiy obyektni ham berish mumkin. Teskari tomoni: shakli bir xil, lekin ma'nosi boshqa turlarni (so'm va foiz) TypeScript farqlamaydi.
Bu darsda
- TypeScript turlarni qanday solishtirishini — "kamida shu xususiyatlar bor" qoidasini — tushunasiz.
- Ko'proq xususiyatli obyekt nega mos, kamrog'i nega mos emasligini bilasiz.
- Strukturaviy moslik va ortiqcha xususiyat tekshiruvi orasidagi farqni ajratasiz.
- Klasslar ham shakl bo'yicha solishtirilishini va bundan kelib chiqadigan tuzoqni ko'rasiz.
- "Nominal emaslik" muammosini taniysiz: bir xil shakldagi turli ma'nolar.
Oldin bilishingiz kerak: Funksiyalarni tiplash, Obyekt turlari, class sintaksisi.
1. Nega bu kerak?
Obyekt turlari darsida bir hodisaga duch keldik va "keyinroq" dedik. spicy xususiyati ortiqcha bo'lgan obyekt o'zgaruvchi orqali berilsa — xato yo'q edi. Funksiyalar darsida esa kamroq parametrli funksiya mos keldi. Ikkalasining ortida bitta qoida turibdi. Bugun uni ochamiz.
«Bahor» menyusida taomlar (Dish klassi), ichimliklar (oddiy obyektlar) va chekdagi qatorlar bor. Sardor narx taxtasini chiqaradigan funksiya yozdi:
type Priced = { name: string; price: number };
function boardLine(item: Priced): string {
return `${item.name}: ${item.price} so'm`;
}
class Dish {
name: string;
price: number;
cookMinutes: number;
constructor(name: string, price: number, cookMinutes: number) {
this.name = name;
this.price = price;
this.cookMinutes = cookMinutes;
}
}
const osh = new Dish("Osh", 35000, 40);
const tea = { name: "Ko'k choy", price: 5000, hot: true };
console.log(boardLine(osh));
console.log(boardLine(tea));Konsolda:
Osh: 35000 so'm
Ko'k choy: 5000 so'mDish hech qayerda "men Priced man" demagan. tea ning esa umuman nomli turi yo'q. Lekin ikkalasi ham boardLine ga berildi va tsc indamadi. Java yoki C# kabi tillarda (boshqa dasturlash tillari — hozir bilish shart emas) bu ishlamasdi: u yerda klass "men shu turdanman" deb aniq e'lon qilishi kerak. TypeScript esa boshqacha savol beradi.
2. Shakl bo'yicha moslik
2.1 Savol: "kerakli xususiyatlar bormi?"
TypeScript osh ni Priced kutilgan joyga berishdan oldin bitta narsani tekshiradi: Priced talab qilgan har bir xususiyat osh da bormi va turi mosmi? name — bor, satr. price — bor, son. Demak, mos. cookMinutes va hot ga qaralmaydi — ular Priced uchun ortiqcha, xalaqit bermaydi.
Bu — strukturaviy tiplash (structural typing): tur tuzilishi (shakli) bo'yicha solishtiriladi. Uni "o'rdak tiplash" (duck typing) ham deyishadi: "o'rdakdek yursa va o'rdakdek g'ag'illasa — demak, o'rdak". Kundalik o'xshatish — kalit va qulf. Qulf kalitning rangi yoki egasini so'ramaydi, faqat tishlari mos kelishini tekshiradi.
2.2 Bir xil shakl — bir xil tur
Ikki xil nomli, lekin bir xil shakldagi tur bir-birining o'rnida ishlaydi:
type MenuItem = { name: string; price: number };
type ReceiptLine = { name: string; price: number };
const line: ReceiptLine = { name: "Manti", price: 30000 };
const item: MenuItem = line;
console.log(item.name); // MantiMenuItem va ReceiptLine — TypeScript uchun bitta tur, faqat ikki nomli. type va interface darsidagi "taxallus — yangi tur emas" qoidasi obyektlar uchun ham amal qiladi. interface bilan yozilgan bo'lsa ham xuddi shunday.
2.3 Ko'proq — mos, kamroq — yo'q
Yo'nalish muhim. Ko'proq xususiyatli obyekt kamroq talab qiladigan turga mos keladi, teskarisi — yo'q:
type Priced = { name: string; price: number };
function boardLine(item: Priced): string {
return `${item.name}: ${item.price} so'm`;
}
const water = { name: "Suv" };
boardLine(water);Kompilyator:
TS2741: Property 'price' is missing in type '{ name: string; }' but required in type 'Priced'.TypeScript aytyapti: «{ name: string; } turida price yo'q, Priced turida esa u majburiy».
water da price yo'q — funksiya item.price ni o'qisa, undefined olardi. Shuning uchun yetishmaydigan xususiyat har doim xato. Ortiqcha xususiyat esa xavfsiz: funksiya uni bilmaydi va ishlatmaydi.
Buni to'plamlar bilan tasavvur qiling. Tur — qiymatlar to'plami. Talab qancha ko'p bo'lsa, unga mos qiymatlar shuncha kam:
flowchart LR
A["{ name }<br/>eng keng: nomi bor<br/>hamma narsa"] --> B["{ name; price }<br/>nomi va narxi bor"]
B --> C["{ name; price; cookMinutes }<br/>eng tor: taomlar"]
C -. "mos keladi ✅" .-> B
B -. "mos keladi ✅" .-> AO'qlar "torroq turni kengroq turga berish mumkin" degan yo'nalishni ko'rsatadi: har taom — narxli narsa, har narxli narsa — nomli narsa. Teskarisi esa yo'q: har nomli narsaning narxi bo'lavermaydi.
Tekshirib ko'ring:
type Guest = { name: string }vaconst malika = { name: "Malika", phone: "+998 90 000 00 00" };—const g: Guest = malika;xato beradimi?const back: typeof malika = g;chi?
Javob
Birinchisi — mos: malika da kerakli name bor, phone ortiqcha. Ikkinchisi — TS2741: Property 'phone' is missing in type 'Guest' but required in type '{ name: string; phone: string; }'. g ning turi faqat name ni kafolatlaydi — telefon bormi-yo'qmi, TypeScript bilmaydi.
3. Xususiyatlar turlari ham solishtiriladi
3.1 Har xususiyat — alohida
Xususiyat bor bo'lishi yetmaydi — uning turi ham mos bo'lishi kerak:
type PriceTag = { name: string; price: string };
const fromKitchen = { name: "Osh", price: 35000 };
const tag: PriceTag = fromKitchen;Kompilyator:
TS2322: Type '{ name: string; price: number; }' is not assignable to type 'PriceTag'.
Types of property 'price' are incompatible.
Type 'number' is not assignable to type 'string'.Zanjirni pastdan o'qing: "son satrga mos emas" → "price xususiyatlarining turlari mos emas" → "butun obyekt mos emas". TypeScript ichma-ich obyektlarda ham xuddi shunday chuqurlashadi.
3.2 Ixtiyoriy va majburiy
type Priced = { name: string; price: number };
type MaybePriced = { name: string; price?: number };
const gift: MaybePriced = { name: "Non" };
const priced: Priced = gift;Kompilyator:
TS2322: Type 'MaybePriced' is not assignable to type 'Priced'.
Types of property 'price' are incompatible.
Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.MaybePriced ning price i — number | undefined, Priced esa aniq son kutadi. Teskari yo'nalish — Priced dan MaybePriced ga — mos: narxi bor narsa "narxi bo'lishi mumkin" degan turga sig'adi.
3.3 Massivlar va funksiyalar
Qoida hamma joyda bir xil. Dish[] ni readonly Priced[] parametrga berish mumkin — har element mos. Funksiyalar ham shakli bo'yicha solishtiriladi: o'tgan darsdagi "kamroq parametrli funksiya mos" qoidasi — strukturaviy tiplashning funksiyalardagi ko'rinishi.
| Qayerdan → qayerga | Mosmi | Nega |
|---|---|---|
{ name; price; hot } → { name; price } |
ortiqcha xususiyat xalaqit bermaydi | |
{ name } → { name; price } |
TS2741 |
price yetishmaydi |
{ price?: number } → { price: number } |
TS2322 |
undefined bo'lishi mumkin |
{ price: number } → { price?: number } |
son — "son yoki yo'q" ga sig'adi | |
Dish[] → readonly Priced[] |
har element mos |
4. Ortiqcha xususiyat tekshiruvi bilan farqi
Endi Obyekt turlari darsidagi jumboq yechiladi. Bir xil obyekt, ikki xil natija:
type Priced = { name: string; price: number };
const viaVariable = { name: "Choy", price: 5000, hot: true };
const ok: Priced = viaVariable;
const fresh: Priced = { name: "Choy", price: 5000, hot: true };Kompilyator:
TS2353: Object literal may only specify known properties, and 'hot' does not exist in type 'Priced'.TypeScript aytyapti: «obyekt literali faqat ma'lum xususiyatlarni yozishi mumkin, Priced da esa hot yo'q».
Faqat uchinchi qator xato. Moslik qoidasi bo'yicha ikkalasi ham to'g'ri: name va price bor. Lekin yangi yozilgan literalga (freshness) TypeScript qo'shimcha tekshiruv qo'llaydi. Yangi literaldagi ortiqcha xususiyatni hech kim ko'rmaydi — u darhol yo'qoladi, demak bu deyarli aniq imlo xatosi.
| Strukturaviy moslik | Ortiqcha xususiyat tekshiruvi | |
|---|---|---|
| Nimani tekshiradi | kerakli xususiyatlar bormi | ortiqcha xususiyat bormi |
| Qachon | doim | faqat yangi obyekt literalida |
| Maqsad | xavfsizlik (undefined o'qilmasin) |
imlo xatolarini ushlash |
Shu sababli massiv ichidagi literallar ham tekshiriladi: cheapest([{ name: "Osh", price: 1, hot: true }]) — TS2353, chunki bu literallar ham shu joyda yaratilgan.
5. Klasslar ham shakl bo'yicha
5.1 Klass turi — uning ochiq xususiyatlari
TypeScript'da klass nomi ham shakl sifatida ishlaydi. Klass obyekti kutilgan joyga oddiy obyekt berish mumkin:
class Dish {
name: string;
price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}
const fake: Dish = { name: "Osh", price: 35000 };
console.log(fake instanceof Dish); // falsetsc — xatosiz: fake da Dish ning hamma xususiyatlari bor. Lekin ishlash paytida u Dish emas — instanceof false qaytardi (instanceof prototip zanjirini tekshiradi). Klassda metod bo'lsa, oddiy obyektda ham o'sha metod bo'lishi kerak — aks holda TS2741.
5.2 Yopiq # maydon shaklni "noyob" qiladi
Yopiq # maydonli klass bilan bunday qilib bo'lmaydi:
class Receipt {
#number = 1;
guest = "Malika";
}
const forged: Receipt = { guest: "Malika" };Kompilyator:
TS2741: Property '#number' is missing in type '{ guest: string; }' but required in type 'Receipt'.TypeScript aytyapti: «{ guest: string; } da #number yo'q, Receipt da esa u majburiy».
#number ni klassdan tashqarida hech kim yarata olmaydi. Shuning uchun yopiq maydonli klass turi amalda faqat o'z obyektlariga mos keladi. Klasslarni TypeScript'da batafsil — Klasslar TypeScript'da darsida.
Tekshirib ko'ring:
class Table { seats = 4; #id = 7; }vaclass Booth { seats = 4; }berilgan.const t: Booth = new Table();mosmi?const b: Table = new Booth();chi?
Javob
Birinchisi — mos: Booth faqat seats ni talab qiladi, Table da u bor (#id — ortiqcha, xalaqit bermaydi). Ikkinchisi — TS2741: Property '#id' is missing in type 'Booth' but required in type 'Table'. Ikki klass bir-biridan meros olmagan, lekin birinchi yo'nalishda shakl yetarli. Ikkinchisida yopiq maydon yo'q — mos emas.
5.3 vazifalar da: Vazifa va Saralanadigan
Bu qoida vazifalar da allaqachon ishlayapti. saralash.js Vazifa klassini import ham qilmaydi — u faqat shaklni tasvirlaydi:
/**
* @typedef {object} Saralanadigan
* @property {number} id qo'shilish tartibi: kattasi — yangisi
* @property {string} matn
* @property {boolean} bajarildi
*/royxat.js tartibla ga Vazifa klassi obyektlarini beradi (matn — getter), testlar esa oddiy obyektlarni: ({ id, matn, bajarildi }). Ikkalasi ham Saralanadigan ga mos. Modul klassga bog'lanmagan — uni klassiz ham sinash mumkin. Generics va cheklovlar qadamida saralash .ts ga o'tganda ham shu qoladi: Taqqoslovchi = (a: VazifaMalumoti, b: VazifaMalumoti) => number, Vazifa esa import qilinmaydi.
6. TypeScript nimani ushlamaydi: nominal emaslik
Strukturaviy tiplashning narxi — bir xil shakldagi turli ma'nolarni TypeScript ajratmaydi:
type Sum = { amount: number }; // so'mda
type Percent = { amount: number }; // foizda
function addService(bill: Sum, service: Percent): number {
return bill.amount + (bill.amount * service.amount) / 100;
}
const bill: Sum = { amount: 70000 };
const service: Percent = { amount: 10 };
console.log(addService(service, bill)); // 7010Argumentlar almashib ketdi — 10 so'mlik hisobga 70 000 % xizmat haqi. tsc jim: ikkala tur ham { amount: number }. Bu nominal emaslik: TypeScript'da tur nomi tekshiruvga ta'sir qilmaydi.
Ikkinchi misol — keng tur bilan ortiqcha ma'lumotni "yo'qotish":
type Priced = { name: string; price: number };
function total(items: readonly Priced[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
const lines = [{ name: "Somsa", price: 8000, qty: 3 }];
console.log(total(lines)); // 8000Chek qatorida 3 ta somsa, jami esa 8 000 — qty ga hech kim qaramadi. lines Priced[] ga mos, chunki ortiqcha qty xalaqit bermaydi. Mantiq xatosini TypeScript topmaydi.
Himoya yo'llari:
- Nom bilan farqlovchi maydon:
{ kind: "sum"; amount: number }va{ kind: "percent"; amount: number }— endi shakllar har xil. Bu g'oya — Discriminated union darsida. - Brend turlar — faqat tur darajasidagi "yorliq": Branded types darsida.
- Obyekt parametr:
addService({ bill, service })— nomlar bilan berilgan argumentlar adashmaydi.
7. Ko'p uchraydigan xatolar
7.1 Parametrga klass turini yozish
function cheapest(items: Dish[]) — endi ichimliklarni berib bo'lmaydi (TS2741 … 'cookMinutes' is missing). Tuzatish: funksiya faqat ishlatadigan xususiyatlarni talab qilsin — readonly Priced[]. Shunda u taomlar, ichimliklar va testdagi oddiy obyektlar bilan ishlaydi.
7.2 "Turini e'lon qilmagan — demak mos emas" deb o'ylash
implements yoki extends yozilmagani moslikka ta'sir qilmaydi. Tuzatish: xabardagi yetishmaydigan yoki mos kelmaydigan xususiyatga qarang.
7.3 Tur nomi himoya qiladi deb o'ylash
type OrderId = { value: number } va type TableId = { value: number } — bitta tur. Tuzatish: farqlovchi maydon yoki brend tur.
7.4 instanceof ga ishonish
Tur Dish deydi, qiymat esa oddiy obyekt bo'lishi mumkin — instanceof false. Tuzatish: klass obyekti kerak bo'lsa, uni new bilan yarating yoki # maydon qo'shing.
8. Mashqlar
1-mashq (oson): Mos keladimi?
type Contact = { name: string; phone: string }; berilgan.
const a = { name: "Bobur", phone: "+998 90 000 00 00", vip: true }; const c: Contact = a; — xato bormi (ha/yo'q): [:yo'q]. const c2: Contact = { name: "Ali" }; xatosining kodi: TS[:2741]. const c3: Contact = { name: "Ali", phone: "x", vip: true }; xatosining kodi: TS.
Yechim
a— o'zgaruvchi, keraklinamevaphonebor,viportiqcha: strukturaviy moslik — xatosiz.{ name: "Ali" }—phoneyetishmaydi:TS2741.- Uchinchisi — yangi literal va ortiqcha
vip: ortiqcha xususiyat tekshiruvi,TS2353.
2-mashq (o'rta): Nega cookMinutes yo'qoldi?
type Priced = { name: string; price: number };
type Dish = { name: string; price: number; cookMinutes: number };
function cheapest(items: readonly Priced[]): Priced | undefined {
let best: Priced | undefined;
for (const item of items) {
if (best === undefined || item.price < best.price) best = item;
}
return best;
}
const dishes: Dish[] = [
{ name: "Osh", price: 35000, cookMinutes: 40 },
{ name: "Manti", price: 30000, cookMinutes: 50 },
];
console.log(cheapest(dishes)?.cookMinutes);Kompilyator:
TS2339: Property 'cookMinutes' does not exist on type 'Priced'.(1) dishes ni cheapest ga berish nega xatosiz? (2) Natijada cookMinutes nega "yo'qoldi", garchi ishlash paytida u bor bo'lsa ham? (3) Hozirgi bilim bilan tuzating.
Yechim
(1) Har Dish — Priced ga mos: kerakli name va price bor (strukturaviy moslik).
(2) Funksiyaning natija turi — Priced. TypeScript funksiya ichiga qaramaydi, faqat imzoga: "qaytgan narsa — Priced". Haqiqiy obyektda cookMinutes bor, lekin tur uni "unutdi".
(3) Hozircha — natijani Dish sifatida ishlatadigan alohida funksiya:
type Dish = { name: string; price: number; cookMinutes: number };
function cheapestDish(items: readonly Dish[]): Dish | undefined {
let best: Dish | undefined;
for (const item of items) {
if (best === undefined || item.price < best.price) best = item;
}
return best;
}
const dishes: Dish[] = [
{ name: "Osh", price: 35000, cookMinutes: 40 },
{ name: "Manti", price: 30000, cookMinutes: 50 },
];
console.log(cheapestDish(dishes)?.cookMinutes); // 50Ishlaydi, lekin endi ikki deyarli bir xil funksiya. "Qanday tur bersang, o'shani qaytaraman" degan bitta funksiya yozish yo'li bor — Generics: turni parametr qilish darsida. Bu mashq o'sha darsning sababi.
3-mashq (qiyin): Amaliy tajriba — menyu taxtasi
Mashq kurs/mashqlar/15/ da. Sardor 10-strukturaviy/board.ts da eng arzon narsani topadigan funksiyani "klass bilan" yozdi:
// 10-strukturaviy/board.ts — «Bahor» menyu taxtasi
export class Dish {
readonly name: string;
readonly price: number;
readonly cookMinutes: number;
constructor(name: string, price: number, cookMinutes: number) {
this.name = name;
this.price = price;
this.cookMinutes = cookMinutes;
}
}
export function cheapest(items: readonly Dish[]): Dish | undefined {
let best: Dish | undefined;
for (const item of items) {
if (best === undefined || item.price < best.price) best = item;
}
return best;
}Va test — taomlar va ichimlik birga:
// 10-strukturaviy/board.test.ts (birinchi variant)
import { test } from "node:test";
import assert from "node:assert/strict";
import { Dish, cheapest } from "./board.ts";
const osh = new Dish("Osh", 35000, 40);
const tea = { name: "Ko'k choy", price: 5000, hot: true };
test("cheapest: taomlar va ichimlik birga", () => {
assert.equal(cheapest([osh, tea])?.name, "Ko'k choy");
});npx tsc --pretty false— xatoni o'qing. Muammo testdami yoki funksiyada?export type Pricedni e'lon qiling vacheapestfaqat kerakli shaklni talab qilsin.boardLines(items)qo'shing: har narsa uchun"Nomi: narx so'm"qatori.- Testlar: aralash ro'yxat va faqat taomlar; bo'sh ro'yxat;
boardLinesortiqcha xususiyatlarni yozmasligi;instanceofklass obyektini oddiy obyektdan farqlashi.
Yechim
1-qadamda tsc 7.0.2:
10-strukturaviy/board.test.ts(10,31): error TS2741: Property 'cookMinutes' is missing in type '{ name: string; price: number; hot: boolean; }' but required in type 'Dish'.Xato test faylida chiqdi, lekin muammo — funksiyada. cheapest faqat price ni ishlatadi, parametri esa Dish ning hamma xususiyatini (cookMinutes ham) talab qilyapti. Bu «Parametrga klass turini yozish» xatosi.
// 10-strukturaviy/board.ts — «Bahor» menyu taxtasi
// Narxi bor har narsa: taom, ichimlik, sovg'a to'plami...
export type Priced = {
readonly name: string;
readonly price: number;
};
export class Dish {
readonly name: string;
readonly price: number;
readonly cookMinutes: number;
constructor(name: string, price: number, cookMinutes: number) {
this.name = name;
this.price = price;
this.cookMinutes = cookMinutes;
}
}
export function cheapest(
items: readonly Priced[],
): Priced | undefined {
let best: Priced | undefined;
for (const item of items) {
if (best === undefined || item.price < best.price) best = item;
}
return best;
}
export function boardLines(items: readonly Priced[]): string[] {
return items.map((item) => `${item.name}: ${item.price} so'm`);
}Dish va Priced orasida hech qanday bog'lanish yozilmagan — ular faqat shakl bo'yicha mos.
// 10-strukturaviy/board.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { Dish, cheapest, boardLines } from "./board.ts";
const osh = new Dish("Osh", 35000, 40);
const manti = new Dish("Manti", 30000, 50);
const tea = { name: "Ko'k choy", price: 5000, hot: true };
test("cheapest: klass obyekti va oddiy obyekt birga", () => {
assert.equal(cheapest([osh, manti, tea])?.name, "Ko'k choy");
assert.equal(cheapest([osh, manti])?.name, "Manti");
});
test("cheapest: bo'sh ro'yxat — undefined", () => {
assert.equal(cheapest([]), undefined);
});
test("boardLines: ortiqcha xususiyatlar yozilmaydi", () => {
assert.deepEqual(boardLines([osh, tea]), [
"Osh: 35000 so'm",
"Ko'k choy: 5000 so'm",
]);
});
test("Dish — klass, tea — yo'q: instanceof farqlaydi", () => {
assert.equal(osh instanceof Dish, true);
assert.equal(tea instanceof Dish, false);
});tea ni oldin o'zgaruvchiga oldik. Agar uni to'g'ridan-to'g'ri yozsangiz — cheapest([osh, { name: "Ko'k choy", price: 5000, hot: true }]) — TS2353 chiqadi: massiv ichidagi yangi literal ortiqcha xususiyat tekshiruvidan o'tadi. npx tsc --pretty false — chiqishsiz. node --test 10-strukturaviy/board.test.ts — bizda (Node 24.21.0):
✔ cheapest: klass obyekti va oddiy obyekt birga (2.7879ms)
✔ cheapest: bo'sh ro'yxat — undefined (0.4596ms)
✔ boardLines: ortiqcha xususiyatlar yozilmaydi (2.5257ms)
✔ Dish — klass, tea — yo'q: instanceof farqlaydi (0.4442ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 334.5347XATOLAR.md ga bu darsdagi zanjirli xabarni qo'shing: TS2322 … Types of property 'price' are incompatible, va TS2741 ning # maydonli ko'rinishi. Keyin kurs/mashqlar papkasidan:
git add 15/10-strukturaviy 15/XATOLAR.md
git commit -m "15/10: board.ts — strukturaviy moslik, Priced"9. Real ishda
- Testlar — strukturaviy tiplashning eng katta yutug'i: haqiqiy klass o'rniga oddiy obyekt (soxta ma'lumot — mock) berish mumkin,
vazifalardagisaralashtestlari kabi. - Kutubxonalar bilan ishlash: kutubxona
{ x: number; y: number }kutsa, o'zingizningPointklassingiz ham, oddiy obyekt ham mos keladi — hech qanday "adapter" yozilmaydi. - API javoblari odatda o'zingiz yozgan turga strukturaviy moslanadi. Lekin moslik faqat kompilyatsiyada tekshiriladi — ishlash paytidagi ma'lumot boshqacha bo'lishi mumkin (API ma'lumotlarini tiplash).
- Intervyu: "Structural va nominal typing farqi?", "Nega ortiqcha xususiyatli obyekt ba'zan xato beradi, ba'zan yo'q?" — TypeScript intervyusining klassik savollari.
Xulosa
- TypeScript turlarni shakl bo'yicha solishtiradi: kerakli xususiyatlar bor va turlari mos bo'lsa — mos. Nomi va kelib chiqishi ahamiyatsiz.
- Ko'proq xususiyat — mos, yetishmaydigan xususiyat —
TS2741. Xususiyat turlari ham, ixtiyoriylik ham tekshiriladi. - Ortiqcha xususiyat tekshiruvi — alohida qoida, faqat yangi obyekt literalida (
TS2353). - Klass turi — uning ochiq xususiyatlari: oddiy obyekt ham mos keladi, lekin
instanceoffarqlaydi.#maydon klassni "noyob" qiladi. - Nominal emaslik: bir xil shakldagi turli ma'nolarni (so'm va foiz) TypeScript ajratmaydi — farqlovchi maydon yoki brend tur kerak.
Keyingi dars: Narrowing: turni toraytirish — typeof, in, instanceof va tenglik tekshiruvlaridan keyin TypeScript union turini qanday aniqroq turga toraytirishini ko'ramiz.
Manbalar
- TypeScript Handbook: "Type Compatibility" — typescriptlang.org/docs/handbook/type-compatibility.html
- TypeScript Handbook: "Object Types" → Excess Property Checks — typescriptlang.org/docs/handbook/2/objects.html
- TypeScript FAQ: "Why doesn't type checking reject … nominal types?" — github.com/microsoft/TypeScript/wiki/FAQ
- TypeScript Handbook: "Classes" → Relationships Between Classes — typescriptlang.org/docs/handbook/2/classes.html
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!