TypeScript'da massivlar, kortejlar va kolleksiyalarni qanday tiplash kerak?

MiddleTypeScript #typescript #arrays #tuples

Savol

Massivlarni (T[] va Array<T>), kortejlarni (tuples) va Map, Set, Record kabi kolleksiyalarni qanday tiplash kerak?

Qisqa javob

T[] va Array<T> — bir xil tipdagi elementlarga ega massivni tiplash uchun ikkita teng huquqli sintaksis. Kortej ([T, U, ...]) har bir elementning tipi pozitsiya bo'yicha belgilangan, qat'iy uzunlikdagi massivni tasvirlaydi. Map<K, V>, Set<T> va Record<K, V> — kalit-qiymat va to'plamlarni tiplash uchun generic tiplar.

Batafsil javob

T[] vs Array<T> — semantik jihatdan bir xil, farq faqat sintaktik. T[] qisqaroq va odatiyroq, Array<T> esa murakkab tiplar uchun qulay (ortiqcha qavslardan qochadi) va bu generic ekanligini aniq ko'rsatadi:

let names: string[] = ['a', 'b']
let ids: Array<number> = [1, 2, 3]
let matrix: number[][] = [[1, 2], [3, 4]] // massivlar massivi

Kortejlar (tuples) — qat'iy uzunlikdagi massivlar bo'lib, ularda ham tip, ham elementning pozitsiyasi muhim. Barcha elementlari bir xil tipda va uzunligi cheklanmagan oddiy massivdan farqli o'laroq:

let point: [number, number] = [10, 20]
let entry: [string, number, boolean] = ['age', 30, true]

// nomlangan elementlar (faqat hujjatlashtirish uchun, tip tekshiruviga ta'sir qilmaydi)
let range: [start: number, end: number] = [0, 100]

// ixtiyoriy va rest-elementlar
let cssRule: [property: string, value: string, important?: boolean] = ['color', 'red']
let path: [root: string, ...segments: string[]] = ['/', 'users', '42']

Kortejlar ko'pincha bir nechta qiymat qaytaradigan funksiyalarning qaytariladigan tipi sifatida ishlatiladi (masalan, React'ning useState funksiyasi [value, setValue] qaytaradi).

Map<K, V> va Set<T> — o'rnatilgan kolleksiyalarning tiplashtirilgan versiyalari:

const cache: Map<string, number> = new Map()
cache.set('a', 1)

const uniqueIds: Set<number> = new Set([1, 2, 3])

Record<K, V> — barcha kalitlari bir xil K tipida bo'lib, V tipidagi qiymatlarga bog'langan obyekt uchun utility-tip. Aslida — { [key: string]: V }ga tip xavfsizligini saqlaydigan alternativa, ayniqsa K aniq string literallar birlashmasi (union) bo'lganda foydali, chunki bunda TypeScript barcha kalitlar mavjud bo'lishini talab qiladi:

type Role = 'admin' | 'user' | 'guest'

const permissions: Record<Role, string[]> = {
  admin: ['read', 'write', 'delete'],
  user: ['read', 'write'],
  guest: ['read'],
} // Role kalitlaridan birortasi unutilsa — kompilyatsiya xatosi

Misol

type Status = 'pending' | 'success' | 'error'

// React useState'ga o'xshash, qaytariladigan tip sifatida kortej
function useToggle(initial: boolean): [boolean, () => void] {
  let state = initial
  const toggle = () => { state = !state }
  return [state, toggle]
}

const [isOpen, toggleOpen] = useToggle(false)

// barcha statuslar uchun qat'iy handler'lar xaritasi uchun Record
const statusHandlers: Record<Status, (msg: string) => void> = {
  pending: (msg) => console.log('⏳', msg),
  success: (msg) => console.log('✅', msg),
  error: (msg) => console.error('❌', msg),
}

// tiplashtirilgan kalitlar va qiymatlarga ega kesh uchun Map
const requestCache = new Map<string, Promise<unknown>>()

function getCached<T>(key: string, loader: () => Promise<T>): Promise<T> {
  if (!requestCache.has(key)) requestCache.set(key, loader())
  return requestCache.get(key) as Promise<T>
}

Qo'shimcha savollar

  • readonly T[] oddiy T[]dan nimasi bilan farq qiladi va uni qachon ishlatish kerak?
  • const arr = [1, 'a'] yozilganda TypeScript kortej tipini oddiy massivga nisbatan qanday chiqarib oladi?
  • Record<string, T> bilan { [key: string]: T } indeks signaturasi o'rtasidagi farq nimada?