Tuple — aniq uzunlik, labeled tuple, optional element

~15 daq · TypeScript · Asosiy Turlar

Fayl yuklash funksiyasi ikki natija qaytaradi: muvaffaqiyatmi va xabar:

function yuklash(fayl: File) {
  if (fayl.size > 5_000_000) return [false, "Fayl juda katta"];
  return [true, "Yuklandi"];
}

const natija = yuklash(fayl);
if (natija[0]) {            // boolean? string?
  console.log(natija[1]);   // TypeScript bilmaydi
}

TypeScript natija ni (boolean | string)[] deb tushunadi — har element boolean ham bo'lishi, string ham bo'lishi mumkin. natija[0] qaysi tur ekanini bilmaydi.

Tuple bu muammoni hal qiladi: har pozitsiyaning turi aniq belgilanadi.


Tuple nima?

Aniq element soni va har pozitsiya turi belgilangan massiv:

string[]          →  istalgancha element, hammasi string
[boolean, string] →  aynan 2 element: [0] boolean, [1] string

Yuqoridagi funksiya to'g'ri yozilsa:

function yuklash(fayl: File): [boolean, string] {
  if (fayl.size > 5_000_000) return [false, "Fayl juda katta"];
  return [true, "Yuklandi"];
}

const [muvaffaqiyat, xabar] = yuklash(fayl); // destructuring
//     ↑ boolean           ↑ string — TypeScript biladi

Tuple e'lon qilish

const koordinata: [number, number]  = [41.2995, 69.2401];
const foydalanuvchi: [string, number] = ["Jasur", 25];

Element soni qat'iy — kam ham, ko'p ham bo'lmaydi:

const rang: [number, number, number] = [255, 128, 0];     // ✅
const rang: [number, number, number] = [255, 128];         // ❌ — 3 ta kerak
const rang: [number, number, number] = [255, 128, 0, 50];  // ❌ — 3 ta kerak

Har pozitsiyada TypeScript tur biladi

const user: [string, number] = ["Jasur", 25];

user[0];              // string
user[1];              // number
user[0].toUpperCase() // ✅ — string metodi
user[1].toFixed(2)    // ✅ — number metodi
user[0].toFixed(2)    // ❌ — string da toFixed yo'q
user[2]               // ❌ — 3-pozitsiya yo'q

Labeled tuple — pozitsiyalarga nom

Oddiy tuple da [0], [1] — nima ekanini kontekstdan bilasiz. Labeled tuple nom beradi:

// Labelsiz
const koordinata: [number, number] = [41.2995, 69.2401];

// Labeled — darhol aniq
const koordinata: [lat: number, lng: number] = [41.2995, 69.2401];

Muharrirda autocomplete ko'rsatganda lat, lng chiqadi — o'ylab o'tirish shart emas.


Optional element — ?

Tuple ning oxirgi elementi ixtiyoriy bo'lishi mumkin:

type Natija = [boolean, string?];

const ok:   Natija = [true];            // ✅ — xabar ixtiyoriy
const xato: Natija = [false, "Xato!"]; // ✅ — xabar bor

Amalda — React useState

useState tuple qaytaradi:

const [son, setSon] = useState(0);
//     ↑     ↑
//  number  Dispatch<SetStateAction<number>>

Destructuring bilan har element o'z nomini oladi — son[0], son[1] emas.


Tez-tez uchraydigan xatolar

Pozitsiyalarni almashtirish:

type UserTuple = [string, number]; // [ism, yosh]

const u: UserTuple = [25, "Jasur"];
// ❌ — [0] string bo'lishi kerak, son berildi

Tuple ga element qo'shishga urinish:

const koordinata: [number, number] = [41.2995, 69.2401];

koordinata.push(100); // ❌ — uzunlik qat'iy

Ko'p elementda ob'ekt afzalroq:

// Tuple — nima ekanini eslab qolish kerak
type TolovTuri = [number, string, boolean, Date];

// Ob'ekt — o'z-o'zini tushuntiradi
type TolovTuri = {
  narxi:       number;
  valyuta:     string;
  tasdiqlandi: boolean;
  sana:        Date;
};

Ikki-uch elementdan ko'p bo'lsa — ob'ekt yaxshiroq.


Xulosa

string[]          →  istalgancha, hammasi string
[string, number]  →  aynan 2 ta: [0] string, [1] number

[lat: number, lng: number]  →  labeled — pozitsiyaga nom
[boolean, string?]          →  optional oxirgi element

Tuple — ikki-uch qiymatni birga qaytarish kerak bo'lganda (muvaffaqiyat + xabar, koordinata, React useState). Ko'p elementda ob'ekt afzalroq.


Keyingi dars

10-dars: Object tur — inline tipizatsiya, nested object