TypeScript

Asosiy turlar

TypeScript'ning yuragi โ€” uning turlar tizimi. Ushbu darsda biz asosiy turlar bilan tanishamiz: qanday qilib o'zgaruvchiga tur berish, massiv va kortejlar (tuple) bilan ishlash, hamda any, unknown, void kabi maxsus turlarni tushunish. JavaScript'ning typeof qaytaradigan turlarini bilsangiz, bu dars siz uchun tanish tuyuladi.

Tur izohi (type annotation)

O'zgaruvchining turini belgilash uchun uning nomidan keyin ikki nuqta va tur nomini yozamiz. Bu tur izohi deyiladi:

let yosh: number = 25;
let ism: string = "Ali";
let faol: boolean = true;

Bu yerda umumiy shakl: let <nom>: <tur> = <qiymat> ko'rinishida. Agar noto'g'ri turdagi qiymat berilsa, kompilyator xato beradi:

let yosh: number = 25;
yosh = "o'ttiz";
// Xato: Type 'string' is not assignable to type 'number'.

Ibtidoiy (primitive) turlar: string, number, boolean

JavaScript'da uchta asosiy ibtidoiy tur bor va TypeScript ularni bir xil nomlar bilan ataydi. Muhim: tur nomlari kichik harflar bilan yoziladi (string, number, boolean) โ€” katta harfli String, Number emas:

let salom: string = "Salom dunyo";
let narx: number = 199.99;
let ochiq: boolean = false;

// number barcha sonlar uchun: butun, kasr, manfiy
let butun: number = 42;
let kasr: number = 3.14;
let oltilik: number = 0xff;
Tur nomlarini kichik harf bilan yozing. String, Number (katta harfli) โ€” bular JavaScript'ning o'rovchi obyekt (wrapper) turlari bo'lib, ularni tur izohida ishlatish tavsiya etilmaydi.

Massivlar (arrays)

Massiv turini yozishning ikkita usuli bor va ikkalasi bir xil ma'noni bildiradi. Birinchisi โ€” element turidan keyin [] qo'yish:

let sonlar: number[] = [1, 2, 3];
let ismlar: string[] = ["Ali", "Vali"];
let bayroqlar: boolean[] = [true, false, true];

Ikkinchisi โ€” generik Array sintaksisi. Bu yozuv burchak qavslar ichida element turini oladi:

let sonlar: Array<number> = [1, 2, 3];
let ismlar: Array<string> = ["Ali", "Vali"];

Endi massivga noto'g'ri turdagi element qo'shsak, xato chiqadi:

let sonlar: number[] = [1, 2, 3];
sonlar.push(4);       // OK
sonlar.push("besh");  // Xato: Argument of type 'string'
                      // is not assignable to parameter of type 'number'.
number[] va Array<number> โ€” bir xil narsa. number[] shakli qisqaroq bo'lgani uchun ko'proq ishlatiladi.

Kortej (tuple)

Kortej (tuple) โ€” bu uzunligi va har bir pozitsiyadagi elementning turi aniq belgilangan massiv. Oddiy massivda barcha elementlar bir turda bo'ladi; kortejda esa har bir o'rin o'z turiga ega bo'lishi mumkin:

// birinchi element โ€” string, ikkinchisi โ€” number
let odam: [string, number] = ["Ali", 25];

console.log(odam[0]); // "Ali" (string)
console.log(odam[1]); // 25 (number)

Tartibni buzsak yoki noto'g'ri tur bersak, xato chiqadi:

let odam: [string, number] = ["Ali", 25];
odam = [25, "Ali"];
// Xato: Type 'number' is not assignable to type 'string'.

Kortejlar, masalan, funksiyadan bir nechta bog'liq qiymatni qaytarishda qulay:

function koordinata(): [number, number] {
  return [41.31, 69.24];
}

let [x, y] = koordinata();

any โ€” turlar tekshiruvidan chiqish

any โ€” bu maxsus tur bo'lib, u "har qanday qiymat bo'lishi mumkin, tekshirma" degan ma'noni bildiradi. any turli o'zgaruvchi bilan hamma narsani qilish mumkin โ€” TypeScript tur tekshiruvini butunlay o'chiradi:

let biror: any = "matn";
biror = 42;        // OK
biror = true;      // OK
biror.hohla();     // OK (lekin ishga tushganda buziladi!)
biror.foo.bar.baz; // OK (tekshirilmaydi)
any โ€” TypeScript'ning barcha himoyasini o'chiradi. Uni ishlatganingizda kod aslida oddiy JavaScript'ga aylanadi. Iloji boricha anydan qoching โ€” u faqat vaqtinchalik yechim yoki tashqi kutubxonalar bilan ishlashda kerak bo'ladi.

unknown โ€” xavfsiz "noma'lum"

unknown โ€” anyning xavfsiz muqobili. U ham "tur noma'lum" degani, lekin farqi shundaki: unknown turli qiymat bilan biror amal qilishdan oldin uning turini tekshirishga majbur qiladi:

let biror: unknown = "matn";

// to'g'ridan-to'g'ri ishlatib bo'lmaydi:
biror.toUpperCase();
// Xato: 'biror' is of type 'unknown'.

// avval turni tekshirish kerak:
if (typeof biror === "string") {
  console.log(biror.toUpperCase()); // endi OK
}
Qoida: agar tur haqiqatan noma'lum bo'lsa, any o'rniga unknown ishlating. U sizni turni tekshirishga undaydi va shu bilan xatolardan himoyalaydi.

void โ€” qaytarilmaydigan qiymat

void โ€” funksiya hech narsa qaytarmasligini bildirish uchun ishlatiladi. Odatda faqat yon ta'sir (masalan, konsolga chop etish) qiladigan funksiyalarning qaytish turi:

function xabarBer(matn: string): void {
  console.log(matn);
  // return yo'q
}

void asosan funksiyalar kontekstida ma'noli. O'zgaruvchiga void tur berish deyarli hech qachon kerak bo'lmaydi.

null va undefined

JavaScript'dagi null va undefined qiymatlari TypeScript'da o'zining nomdosh turlariga ega:

let bosh: null = null;
let aniqmas: undefined = undefined;

Ko'pincha bu turlar union orqali boshqa turlar bilan birga ishlatiladi โ€” bu "qiymat bor yoki yo'q" holatini ifodalash uchun (union haqida keyingi darsda batafsil):

let ism: string | null = "Ali";
ism = null; // OK โ€” endi null ham ruxsat etilgan
strictNullChecks sozlamasi yoqilganda (tavsiya etiladi) TypeScript null va undefinedni jiddiy tekshiradi va "null bo'lishi mumkin" qiymatlarni tasodifan ishlatishdan himoya qiladi.

Tur xulosasi (type inference)

TypeScript juda aqlli: agar o'zgaruvchini boshlang'ich qiymat bilan e'lon qilsangiz, u turni o'zi topib oladi. Bunga tur xulosasi (type inference) deyiladi. Ya'ni har doim ham tur yozish shart emas:

let ism = "Ali";   // TS o'zi biladi: string
let yosh = 25;      // TS o'zi biladi: number
let faol = true;    // TS o'zi biladi: boolean

ism = 42; // Xato: Type 'number' is not assignable to type 'string'.

Bu yerda ismga tur yozmaganimiz bilan, TypeScript uni string deb hisoblaydi (chunki boshlang'ich qiymati matn). Shuning uchun keyin son berishga urinsak, xato chiqadi.

Amaliy qoida: agar o'zgaruvchi darrov qiymat bilan e'lon qilinsa, turni yozmaslik odatiy hol. Turni funksiya parametrlariga, murakkab holatlarga yoki qiymat keyinroq beriladigan o'zgaruvchilarga yozamiz.

Literal turlar

TypeScript'da tur nafaqat string yoki number kabi keng bo'lishi, balki aniq bir qiymat ham bo'lishi mumkin. Bu literal tur deyiladi:

let yonalish: "chap" | "o'ng" = "chap";
yonalish = "o'ng";  // OK
yonalish = "orqa";  // Xato: Type '"orqa"' is not
                    // assignable to type '"chap" | "o'ng"'.

Bu yerda yonalish faqat "chap" yoki "o'ng" qiymatlaridan birini qabul qiladi. Literal turlar union bilan birga sanab o'tiladigan (enum kabi) holatlarni ifodalash uchun juda kuchli:

type Holat = "kutilyapti" | "tayyor" | "bekor";

function holatOrnat(h: Holat): void {
  console.log("Holat: " + h);
}

holatOrnat("tayyor"); // OK
holatOrnat("xato");   // Xato: noto'g'ri literal

Xulosa