Interface vs Type alias — qachon qaysi, farqlari

~15 daq · TypeScript · Interface

Ob'ekt tuzilmasini belgilash kerak. Ikki yo'l bor:

interface Foydalanuvchi {
  ism:   string;
  yosh:  number;
}

type Foydalanuvchi = {
  ism:   string;
  yosh:  number;
};

Ikkalasi ko'p holda bir xil ishlaydi. Lekin farqlar bor — va bu farqlar qachon qaysinisini tanlashni belgilaydi.


Farq 1 — nima uchun ishlatiladi

interface  →  ob'ekt shakli, class shartnomasi
type       →  istalgan tur: union, tuple, primitive, ob'ekt

type ko'proq narsa qila oladi:

type Id        = number | string;           // union
type Koordinat = [number, number];          // tuple
type Qayta     = (x: number) => number;     // funksiya
type Holat     = "faol" | "nofaol";         // literal union

interface bular uchun ishlatib bo'lmaydi — faqat ob'ekt shakli uchun.


Farq 2 — kengaytirish

Interface: extends bilan kengaytirish:

interface Hayvon { ism: string; }

interface It extends Hayvon {
  zot: string;
}

Type: & bilan kengaytirish:

type Hayvon = { ism: string; };

type It = Hayvon & {
  zot: string;
};

Ikkalasi bir xil natija — lekin interface extends xatoliklarni aniqroq ko'rsatadi.


Farq 3 — Declaration merging

Bu eng katta farq. Interface bir xil nomda ikki marta e'lon qilinsa — avtomatik birlashadi:

interface Foydalanuvchi { ism: string; }
interface Foydalanuvchi { yosh: number; }

// Natija:
// interface Foydalanuvchi { ism: string; yosh: number; }

type bilan bu imkonsiz — xato chiqadi:

type Foydalanuvchi = { ism: string; };
type Foydalanuvchi = { yosh: number; }; // ❌ — Duplicate identifier

Declaration merging qachon kerak? Kutubxona turlarini kengaytirishda — masalan express ga yangi xususiyat qo'shish:

// express ning Request turiga yangi xususiyat qo'shish
declare namespace Express {
  interface Request {
    user?: Foydalanuvchi; // barcha route larda req.user bo'ladi
  }
}

Farq 4 — xato xabarlari

interface A { x: string; }
type B = { x: string; };

Xato chiqganda TypeScript A ni "Foydalanuvchi" nomi bilan ko'rsatadi. B ni esa ba'zan { x: string } ko'rinishida yoyib ko'rsatadi — murakkabroq turlarda xato xabari o'qish qiyin bo'lishi mumkin.


Qachon qaysi?

Interface                            Type alias
──────────────────────────────────   ────────────────────────────────
ob'ekt shakli                        union: string | number
class implements                     tuple: [string, number]
extends bilan kengaytirish           funksiya turi
kutubxona turlarini kengaytirish     literal: "faol" | "nofaol"
declaration merging kerak bo'lsa     primitive nom berish: type Id = number

Amaliy qoida:

  • Ob'ekt tuzilmasi → interface
  • Boshqa hamma narsa → type
  • Ikkalasi ham ishlasa → interface (zamonaviy TypeScript tavsiyasi)

Tez-tez uchraydigan xatolar

Union uchun interface ishlatishga urinish:

interface Holat = "faol" | "nofaol"; // ❌ — sintaksis xato

type Holat = "faol" | "nofaol"; // ✅

type bilan declaration merging qilishga urinish:

type Config = { port: number; };
type Config = { host: string; }; // ❌ — Duplicate identifier

Xulosa

Imkoniyat             interface    type
────────────────────  ─────────   ─────
Ob'ekt shakli             ✅         ✅
Union, tuple, literal     ❌         ✅
extends                   ✅     & bilan
Declaration merging       ✅         ❌
Class implements          ✅         ✅

Ko'p holda ikkalasi ham ishlaydi. Ob'ekt shakli uchun interface — qolgan hamma narsa uchun type.


Keyingi dars

21-dars: Declaration merging — interface avtomatik birlashtirish