8-bo‘lim
interface va type
Ikki yozuvning ustma-ust tushadigan qismi, e'lon birlashuvi, indeks imzosi farqi va qaysi birini tanlash.
Ushbu bo‘lim mundarijasi
Obyekt shaklini tasvirlashning ikkita yo'li bor: interface va
type. 4-bobdan beri type ishlatib keldik.
Ko'p holatda ular bir xil ishlaydi. Farqlari kam, lekin ularning ikkitasi amalda tez-tez uchraydi.
Bir xil ish, ikki yozuv #
interface Mahsulot1 {
nomi: string;
narx: number;
}
type Mahsulot2 = {
nomi: string;
narx: number;
};
const a: Mahsulot1 = { nomi: "Olma", narx: 12000 };
const b: Mahsulot2 = { nomi: "Anor", narx: 25000 };
const c: Mahsulot1 = b;
const d: Mahsulot2 = a;
console.log(a.nomi, b.nomi, c.narx, d.narx);
tsx src/ikki.ts
Olma Anor 25000 12000
E'tibor bering: Mahsulot2 turidagi qiymat Mahsulot1 ga
bemalol berildi va aksincha. TypeScript nomga emas,
tuzilmaga qaraydi - qaysi kalit so'z bilan yozilgani muhim
emas.
Yozuvdagi farqlar:
interface | type | |
|---|---|---|
| Tenglik belgisi | Yo'q | Bor: type X = {...} |
| Oxirida nuqtali vergul | Kerak emas | Kerak |
extends va & #
interface Shaxs {
nomi: string;
}
interface Xodim extends Shaxs {
lavozim: string;
}
type Shaxs2 = { nomi: string };
type Xodim2 = Shaxs2 & { lavozim: string };
const x: Xodim = { nomi: "Husanboy", lavozim: "dasturchi" };
const y: Xodim2 = { nomi: "Ali", lavozim: "sotuvchi" };
console.log(x.lavozim, y.lavozim);
tsx src/kengayt.ts
dasturchi sotuvchi
extends bir nechta turdan meros olishi mumkin:
interface Nomli {
nomi: string;
}
interface Narxli {
narx: number;
}
interface Mahsulot extends Nomli, Narxli {
soni: number;
}
const m: Mahsulot = { nomi: "Olma", narx: 12000, soni: 3 };
console.log(m.nomi, m.narx * m.soni);
tsx src/kop.ts
Olma 36000
Ikkisini aralashtirish ham mumkin - interface type ni
kengaytira oladi:
type Shaxs = { nomi: string };
interface Xodim extends Shaxs {
lavozim: string;
}
const x: Xodim = { nomi: "Husanboy", lavozim: "dasturchi" };
console.log(x.nomi, x.lavozim);
tsx src/aralash.ts
Husanboy dasturchi
Lekin faqat obyekt shaklidagi turni:
type Id = string | number;
interface Kalit extends Id {
nomi: string;
}
tsc --noEmit 2>&1 | fold -sw 74
src/aralash2.ts(3,25): error TS2312: An interface can only extend an
object type or intersection of object types with statically known members.
Birinchi haqiqiy farq: e'lon birlashuvi #
Bir nomli interface ni bir necha marta yozish mumkin -
ular qo'shiladi:
interface Sozlama {
port: number;
}
interface Sozlama {
host: string;
}
const s: Sozlama = { port: 8080, host: "localhost" };
console.log(s.host, s.port);
tsx src/birlash.ts
localhost 8080
Ikkita alohida e'lon bitta turga aylandi. type da esa:
type Sozlama = {
port: number;
};
type Sozlama = {
host: string;
};
tsc --noEmit 2>&1 | fold -sw 74
src/birlash2.ts(1,6): error TS2300: Duplicate identifier 'Sozlama'.
src/birlash2.ts(5,6): error TS2300: Duplicate identifier 'Sozlama'.
Kuchi: tashqi kutubxonaning turini to'ldirish mumkin.
Masalan Express ning Request interfeysiga o'z maydoningizni
qo'shasiz va butun loyihada u ko'rinadi.
Xavfi: o'z kodingizda tasodifan ikkita bir nomli
interface yozsangiz, kompilyator hech narsa demaydi -
ular jimgina qo'shilib ketadi. type esa darhol
TS2300 beradi.
Loyiha ichidagi turlar uchun bu - type foydasiga bitta
ovoz.
Ikkinchi farq: type ko'proq narsani ifodalaydi #
type Id = string | number;
type Nuqta = [number, number];
type Ism = string;
type Ishlov = (xabar: string) => void;
const i: Id = 101;
const n: Nuqta = [41, 69];
const m: Ism = "Olma";
const f: Ishlov = (s) => console.log("xabar:", s);
console.log(i, n.join(","), m);
f("salom");
tsx src/faqat.ts
101 41,69 Olma
xabar: salom
interface esa faqat obyekt shaklini tasvirlaydi:
interface Id = string | number;
tsc --noEmit 2>&1 | fold -sw 74 | head -6
src/faqat2.ts(1,14): error TS1005: '{' expected.
Bu sintaksis xatosi - interface dan keyin doim { kutiladi.
Uchinchi farq: ziddiyatda ovoz chiqarish #
6-bobda ko'rdik: & bilan ziddiyatli maydon jimgina never
bo'ladi. extends esa darhol shikoyat qiladi:
interface A {
id: number;
}
interface B extends A {
id: string;
}
tsc --noEmit 2>&1 | fold -sw 74
src/zid.ts(5,11): error TS2430: Interface 'B' incorrectly extends
interface 'A'.
Types of property 'id' are incompatible.
Type 'string' is not assignable to type 'number'.
Xato turning o'zida, 5-qatorda. Endi & bilan:
type A = { id: number };
type B = A & { id: string };
declare const b: B;
b.id.toFixed(0);
tsc --noEmit 2>&1 | fold -sw 74
src/zid2.ts(5,6): error TS2339: Property 'toFixed' does not exist on type
'never'.
Xato 5-qatorda - turdan ancha keyin, ishlatilgan joyda.
Bu - interface foydasiga bitta ovoz.
To'rtinchi farq: indeks imzosi #
Bu eng kutilmagani:
interface Mahsulot1 {
nomi: string;
narx: number;
}
type Mahsulot2 = {
nomi: string;
narx: number;
};
function nechta(x: Record<string, unknown>): number {
return Object.keys(x).length;
}
const b: Mahsulot2 = { nomi: "Anor", narx: 25000 };
console.log(nechta(b));
const a: Mahsulot1 = { nomi: "Olma", narx: 12000 };
console.log(nechta(a));
tsc --noEmit 2>&1 | fold -sw 74
src/indeks.ts(19,20): error TS2345: Argument of type 'Mahsulot1' is not
assignable to parameter of type 'Record<string, unknown>'.
Index signature for type 'string' is missing in type 'Mahsulot1'.
Ikkalasining maydonlari bir xil. type bilan yozilgani o'tdi,
interface bilan yozilgani o'tmadi.
Sabab: interface ni keyinroq birlashtirib kengaytirish
mumkin. Shuning uchun TypeScript "bu turda qanday kalitlar
borligini aniq bilmayman" deb hisoblaydi va yashirin indeks
imzosi bermaydi. type esa o'zgarmas - kalitlari aniq.
Bir xil ishlaydigan narsalar #
Rekursiya ikkalasida ham bor:
interface Tugun {
nomi: string;
bolalar: Tugun[];
}
type Tugun2 = {
nomi: string;
bolalar: Tugun2[];
};
const t: Tugun = {
nomi: "ildiz",
bolalar: [{ nomi: "bola", bolalar: [] }],
};
const u: Tugun2 = { nomi: "ildiz2", bolalar: [] };
console.log(t.bolalar[0].nomi, u.bolalar.length);
tsx src/rekursiv.ts
bola 0
readonly, ? va metod yozuvi ham ikkalasida bir xil:
interface Mahsulot {
readonly id: number;
nomi: string;
tavsif?: string;
narxla(soni: number): number;
}
const m: Mahsulot = {
id: 1,
nomi: "Olma",
narxla: (soni) => soni * 12000,
};
console.log(m.nomi, m.tavsif, m.narxla(3));
tsx src/xossa.ts
Olma undefined 36000
Xato xabarlari ham deyarli bir xil - ikkalasi ham o'z nomini saqlaydi:
interface Mahsulot1 {
nomi: string;
narx: number;
}
type Mahsulot2 = {
nomi: string;
narx: number;
};
const a: Mahsulot1 = { nomi: "Olma" };
const b: Mahsulot2 = { nomi: "Anor" };
tsc --noEmit 2>&1 | fold -sw 74
src/xabar.ts(11,7): error TS2741: Property 'narx' is missing in type '{
nomi: string; }' but required in type 'Mahsulot1'.
src/xabar.ts(12,7): error TS2741: Property 'narx' is missing in type '{
nomi: string; }' but required in type 'Mahsulot2'.
Ilgari type bilan yozilgan tur xato xabarida to'liq
yoyilib ketardi. Zamonaviy TypeScript da (5.x) ikkalasi ham
nomi bilan ko'rsatiladi - yuqoridagi natija shuni tasdiqlaydi.
Yoyilish faqat nomsiz turlarda ({ nomi: string } kabi to'g'ridan
to'g'ri yozilgan shakllarda) qoladi.
Qaysi birini tanlash #
Amalda bu tanlov deyarli hech qachon muhim emas. Muhimi - bir xil ishlatish.
| Holat | Tavsiya |
|---|---|
Sinf implements qiladigan shartnoma | interface |
| Kutubxona turini to'ldirish | interface |
| Union, kortej, funksiya turi | type |
| Utility turlar bilan ishlash (13-bob) | type |
Record<string, unknown> ga berish | type |
| Oddiy obyekt shakli | Ikkalasi ham |
Bu darslikda type ishlatiladi - chunki u hamma narsani
qamraydi va tasodifiy birlashuvdan himoya qiladi. Ko'p
jamoalar esa interface ni tanlaydi. Ikkalasi ham to'g'ri.
Xulosa #
interfacevatypeobyekt shaklini bir xil tasvirlaydi; TypeScript nomga emas, tuzilmaga qaraydi.extendsbir nechta turdan meros oladi;&ham shu ishni qiladi.interfacetypeni kengaytira oladi, lekin faqat obyekt shaklidagisini - union ni emas (TS2312).- E'lon birlashuvi: bir nomli
interfacelar qo'shiladi; bir nomlitypelar esaTS2300beradi. - Birlashuv tashqi kutubxona turini to'ldirish uchun foydali, lekin o'z kodingizda tasodifiy takrorlanishni yashiradi.
- Faqat
typeunion, kortej, funksiya va primitiv turlarni ifodalay oladi. - Ziddiyatda
extendsdarholTS2430beradi,&esa jimginaneverqoldiradi. interfaceyashirin indeks imzosiga ega emas - uniRecord<string, unknown>ga berib bo'lmaydi,typeni esa mumkin.- Rekursiya,
readonly,?va metod yozuvi ikkalasida bir xil. - Zamonaviy TypeScript da ikkalasining xato xabarlari ham turning nomini saqlaydi.
- Eng muhimi - loyiha bo'ylab bittasini tanlab, izchil ishlatish.
- Bir xil maydonli
interfacevatypeyozing va ularni bir-biriga bering. interface X extends Y, Zbilan uchta turdan meros oling.interfacebilantypeni kengaytiring.- Union
typeniextendsqilishga urinib,TS2312ni oling. - Bir nomli ikkita
interfaceyozib, maydonlar qo'shilishini ko'ring. - Xuddi shuni
typebilan qilib,TS2300ni oling. interfacebilan union yozishga urinib, sintaksis xatosini ko'ring.- Ziddiyatli
extendsva ziddiyatli&yozib, xato qaysi qatorda chiqishini solishtiring. Record<string, unknown>kutadigan funksiyagainterfacevatypeqiymatlarini berib, farqni kuzating.- O'z loyihangiz uchun qaysi birini tanlashingizni va nega shundayligini ikki jumlada yozing.
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.