8-bo‘lim

interface va type

Ikki yozuvning ustma-ust tushadigan qismi, e'lon birlashuvi, indeks imzosi farqi va qaysi birini tanlash.

🕑 23 daqiqa o‘qish 📄 749 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Bir xil ish, ikki yozuv
  2. extends va &
  3. Birinchi haqiqiy farq: e'lon birlashuvi
  4. Ikkinchi farq: type ko'proq narsani ifodalaydi
  5. Uchinchi farq: ziddiyatda ovoz chiqarish
  6. To'rtinchi farq: indeks imzosi
  7. Bir xil ishlaydigan narsalar
  8. Qaysi birini tanlash
  9. Xulosa

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 #

TS
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);
Terminal
tsx src/ikki.ts
Natija
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:

interfacetype
Tenglik belgisiYo'qBor: type X = {...}
Oxirida nuqtali vergulKerak emasKerak

extends va & #

TS
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);
Terminal
tsx src/kengayt.ts
Natija
dasturchi sotuvchi

extends bir nechta turdan meros olishi mumkin:

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

Ikkisini aralashtirish ham mumkin - interface type ni kengaytira oladi:

TS
type Shaxs = { nomi: string };

interface Xodim extends Shaxs {
  lavozim: string;
}

const x: Xodim = { nomi: "Husanboy", lavozim: "dasturchi" };
console.log(x.nomi, x.lavozim);
Terminal
tsx src/aralash.ts
Natija
Husanboy dasturchi

Lekin faqat obyekt shaklidagi turni:

TS
type Id = string | number;

interface Kalit extends Id {
  nomi: string;
}
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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:

TS
interface Sozlama {
  port: number;
}

interface Sozlama {
  host: string;
}

const s: Sozlama = { port: 8080, host: "localhost" };
console.log(s.host, s.port);
Terminal
tsx src/birlash.ts
Natija
localhost 8080

Ikkita alohida e'lon bitta turga aylandi. type da esa:

TS
type Sozlama = {
  port: number;
};

type Sozlama = {
  host: string;
};
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/birlash2.ts(1,6): error TS2300: Duplicate identifier 'Sozlama'.
src/birlash2.ts(5,6): error TS2300: Duplicate identifier 'Sozlama'.
Birlashuv - ham kuch, ham xavf

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 #

TS
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");
Terminal
tsx src/faqat.ts
Natija
101 41,69 Olma
xabar: salom

interface esa faqat obyekt shaklini tasvirlaydi:

TS
interface Id = string | number;
Terminal
tsc --noEmit 2>&1 | fold -sw 74 | head -6
Natija
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:

TS
interface A {
  id: number;
}

interface B extends A {
  id: string;
}
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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:

TS
type A = { id: number };
type B = A & { id: string };

declare const b: B;
b.id.toFixed(0);
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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:

TS
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));
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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.

interface va type: to'rtta amaliy farq interface + E'lon birlashuvi - kutubxona turini to'ldirish mumkin + extends ziddiyatda darhol xato beradi (TS2430, turning o'zida) - Union, kortej, primitiv yozib bo'lmaydi - Record<string, unknown> ga bermaydi (yashirin indeks imzosi yo'q) - Tasodifiy bir nomli e'lon jim qo'shiladi Sinflar va ommaviy API uchun type + Union, kortej, funksiya, primitiv - hammasini ifodalaydi + Takroriy nom darhol TS2300 beradi + Record<string, unknown> ga mos keladi + Utility va shartli turlar bilan ishlaydi - & ziddiyati jim never beradi (xato ishlatgan joyda chiqadi) Qolgan hamma narsa uchun Amaliy qoida Bittasini tanlab, loyiha bo'ylab bir xil ishlating. Ikkalasi ham to'g'ri javob. Faqat yuqoridagi to'rtta holatda ataylab boshqasiga o'ting.
Farqlar oz, lekin har biri aniq bir holatda hal qiluvchi

Bir xil ishlaydigan narsalar #

Rekursiya ikkalasida ham bor:

TS
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);
Terminal
tsx src/rekursiv.ts
Natija
bola 0

readonly, ? va metod yozuvi ham ikkalasida bir xil:

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

Xato xabarlari ham deyarli bir xil - ikkalasi ham o'z nomini saqlaydi:

TS
interface Mahsulot1 {
  nomi: string;
  narx: number;
}

type Mahsulot2 = {
  nomi: string;
  narx: number;
};

const a: Mahsulot1 = { nomi: "Olma" };
const b: Mahsulot2 = { nomi: "Anor" };
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
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'.
"type alias xato xabarini yomonlashtiradi" - eskirgan gap

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.

HolatTavsiya
Sinf implements qiladigan shartnomainterface
Kutubxona turini to'ldirishinterface
Union, kortej, funksiya turitype
Utility turlar bilan ishlash (13-bob)type
Record<string, unknown> ga berishtype
Oddiy obyekt shakliIkkalasi 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 #

  • interface va type obyekt shaklini bir xil tasvirlaydi; TypeScript nomga emas, tuzilmaga qaraydi.
  • extends bir nechta turdan meros oladi; & ham shu ishni qiladi.
  • interface type ni kengaytira oladi, lekin faqat obyekt shaklidagisini - union ni emas (TS2312).
  • E'lon birlashuvi: bir nomli interface lar qo'shiladi; bir nomli type lar esa TS2300 beradi.
  • Birlashuv tashqi kutubxona turini to'ldirish uchun foydali, lekin o'z kodingizda tasodifiy takrorlanishni yashiradi.
  • Faqat type union, kortej, funksiya va primitiv turlarni ifodalay oladi.
  • Ziddiyatda extends darhol TS2430 beradi, & esa jimgina never qoldiradi.
  • interface yashirin indeks imzosiga ega emas - uni Record<string, unknown> ga berib bo'lmaydi, type ni 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.
Amaliy topshiriq
  1. Bir xil maydonli interface va type yozing va ularni bir-biriga bering.
  2. interface X extends Y, Z bilan uchta turdan meros oling.
  3. interface bilan type ni kengaytiring.
  4. Union type ni extends qilishga urinib, TS2312 ni oling.
  5. Bir nomli ikkita interface yozib, maydonlar qo'shilishini ko'ring.
  6. Xuddi shuni type bilan qilib, TS2300 ni oling.
  7. interface bilan union yozishga urinib, sintaksis xatosini ko'ring.
  8. Ziddiyatli extends va ziddiyatli & yozib, xato qaysi qatorda chiqishini solishtiring.
  9. Record<string, unknown> kutadigan funksiyaga interface va type qiymatlarini berib, farqni kuzating.
  10. O'z loyihangiz uchun qaysi birini tanlashingizni va nega shundayligini ikki jumlada yozing.

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.