Interfeys va tip aliaslari
Haqiqiy dasturlarda biz ko'pincha oddiy sonlar yoki matnlar emas, balki murakkab obyektlar bilan ishlaymiz โ foydalanuvchi, buyurtma, mahsulot. TypeScript bunday obyektlarning "shaklini" tavsiflash uchun ikkita asosiy vosita beradi: interface (interfeys) va type alias (tip aliasi). Ushbu darsda ularni chuqur o'rganamiz.
interface โ obyekt shaklini tavsiflash
Interfeys โ obyekt qanday xossalarga va qanday turlarga ega bo'lishi kerakligini tavsiflaydigan "shartnoma". Uni interface kalit so'zi bilan e'lon qilamiz:
interface Foydalanuvchi {
ism: string;
yosh: number;
faol: boolean;
}
Endi bu interfeysni tur sifatida ishlatishimiz mumkin. Obyekt interfeysga to'liq mos kelishi shart:
let user: Foydalanuvchi = {
ism: "Ali",
yosh: 25,
faol: true
};
Agar biror xossani tushirib qoldirsak yoki noto'g'ri tur bersak, kompilyator darrov xato ko'rsatadi:
let user: Foydalanuvchi = {
ism: "Ali",
yosh: 25
};
// Xato: Property 'faol' is missing in type
// '{ ism: string; yosh: number; }' but required in type 'Foydalanuvchi'.
Foydalanuvchi, Mahsulot). Bu โ kelishuv (konvensiya), majburiy emas, lekin kodni o'qishni osonlashtiradi.type alias โ tur uchun taxallus
Tip alias (type alias) โ bu istalgan turga nom berish usuli. Uni type kalit so'zi bilan yaratamiz. Obyekt shakli uchun u interfeysga juda o'xshaydi:
type Foydalanuvchi = {
ism: string;
yosh: number;
faol: boolean;
};
let user: Foydalanuvchi = {
ism: "Ali",
yosh: 25,
faol: true
};
Lekin type faqat obyektlar uchun emas โ u istalgan turga nom berishi mumkin. Masalan, ibtidoiy turlar, union yoki kortejlar uchun:
type Yosh = number;
type Ism = string;
type Koordinata = [number, number];
type Holat = "tayyor" | "kutilyapti";
type esa ancha keng โ u har qanday turga (union, kortej, ibtidoiy) nom bera oladi.Ixtiyoriy xossalar (?)
Ba'zi xossalar majburiy bo'lmasligi mumkin. Bunday xossa nomidan keyin savol belgisi ? qo'yamiz. Bu "bu xossa bo'lishi ham, bo'lmasligi ham mumkin" degani:
interface Foydalanuvchi {
ism: string;
yosh: number;
email?: string; // ixtiyoriy
}
// email'siz ham to'g'ri:
let u1: Foydalanuvchi = { ism: "Ali", yosh: 25 };
// email bilan ham to'g'ri:
let u2: Foydalanuvchi = { ism: "Vali", yosh: 30, email: "vali@mail.uz" };
Ixtiyoriy xossaning turi aslida string | undefined bo'ladi โ ya'ni u yo bor, yo undefined. Shuning uchun uni ishlatishdan oldin tekshirish yaxshi odat:
function emailKorsat(u: Foydalanuvchi): void {
if (u.email) {
console.log(u.email.toUpperCase());
} else {
console.log("Email yo'q");
}
}
readonly xossalar
Ba'zi xossalarni yaratilgandan keyin o'zgartirib bo'lmasligi kerak. Bunday xossa oldiga readonly yozamiz. Bu JavaScript'dagi constning obyekt xossalari uchun o'xshashi:
interface Foydalanuvchi {
readonly id: number;
ism: string;
}
let user: Foydalanuvchi = { id: 1, ism: "Ali" };
user.ism = "Vali"; // OK
user.id = 2;
// Xato: Cannot assign to 'id' because it is a read-only property.
readonly faqat kompilyatsiya paytida ishlaydi. Tayyor JavaScript'da bunday cheklov qolmaydi โ bu shunchaki dasturchi uchun xavfsizlik qatlami.Union turlar (|)
Union (birlashma) tur โ bu "bir nechta turdan biri" degani. Turlar orasiga vertikal chiziq | qo'yamiz. Bu "yoki" ma'nosini beradi:
let qiymat: string | number;
qiymat = "matn"; // OK
qiymat = 42; // OK
qiymat = true; // Xato: boolean ruxsat etilmagan
Union tur bilan ishlashda TypeScript sizni turni tekshirishga undaydi. Chunki har bir turda mavjud amallar farq qiladi. Buni tur torayishi (narrowing) deyiladi:
function idKorsat(id: string | number): void {
if (typeof id === "string") {
// bu blokda id โ string
console.log(id.toUpperCase());
} else {
// bu blokda id โ number
console.log(id.toFixed(2));
}
}
Intersection turlar (&)
Intersection (kesishma) tur โ union'ning aksi. U bir nechta turni birlashtirib, hammasini birdaniga talab qiladi. Bunda ampersand & ishlatiladi:
interface Ism {
ism: string;
}
interface Yosh {
yosh: number;
}
// ikkala interfeysni birlashtiradi:
type Odam = Ism & Yosh;
let odam: Odam = {
ism: "Ali",
yosh: 25
};
// ikkala xossa ham majburiy
Ya'ni Ism & Yosh โ bu ism va yosh xossalariga ega bo'lgan obyekt. Union "yoki" bo'lsa, intersection "va" degani.
| (union) โ "yo bu, yo u"; & (intersection) โ "ham bu, ham u".interface va type: farqi qanday?
Ikkalasi ham obyekt shaklini tavsiflay oladi, shuning uchun ko'pincha almashtirsa bo'ladi. Lekin bir nechta muhim farq bor:
- Kengayish (extends): interfeyslar
extendsorqali meros oladi;typeesa intersection (&) bilan birlashtiriladi; - Deklaratsiya birlashuvi: bir nomdagi interfeysni bir necha marta e'lon qilsangiz, ular birlashadi.
typeda bunday emas โ takror e'lon qilish xato beradi; - Kenglik:
typeunion, kortej, ibtidoiy turlarga ham nom bera oladi; interface faqat obyekt shakllari uchun.
Interfeysning extends orqali meros olishi:
interface Hayvon {
ism: string;
}
interface It extends Hayvon {
zot: string;
}
let it: It = { ism: "Rex", zot: "Ovcharka" };
Interfeysning deklaratsiya birlashuvi โ bir nomdagi ikkita interfeys avtomatik birlashadi:
interface Oyna {
eni: number;
}
interface Oyna {
bo'yi: number;
}
// endi Oyna'da ikkala xossa bor:
let o: Oyna = { eni: 100, bo'yi: 200 };
interface tavsiya etiladi (ayniqsa kutubxona/API tavsiflarida). Union, kortej yoki murakkab turlar uchun esa type ishlatiladi. Ko'p loyihalar shu qoidaga amal qiladi.Xulosa
interfaceobyekt shaklini tavsiflaydi โ qanday xossalar va turlar bo'lishini belgilaydi;type(alias) istalgan turga nom beradi โ obyekt, union, kortej, ibtidoiy;?โ ixtiyoriy xossa;readonlyโ o'zgartirib bo'lmaydigan xossa;|(union) โ "turlardan biri";&(intersection) โ "turlarning barchasi birga";- Union bilan ishlashda TypeScript turni tekshirishga (narrowing) undaydi;
interfaceextendsva deklaratsiya birlashuvini qo'llab-quvvatlaydi;typeesa ancha keng qo'llaniladi.