IlmHamroh
JavaScript Full-stack/15-qism. TypeScript25/47-dars17 daqiqa
Mundarija (34)

TypeScript keyof, typeof va indexed access: turlarni qiymatlardan chiqarish

Qisqacha: Turni qo'lda takrorlash o'rniga uni mavjud qiymat yoki turdan chiqarib olish mumkin. typeof MENU — o'zgaruvchining turi, keyof typeof MENU — uning kalitlari ("osh" | "manti"), Dish["price"] — bitta maydon turi, (typeof SIZES)[number] — massiv elementlari union'i. Qiymat o'zgarsa, tur ham o'zi o'zgaradi.

Bu darsda

  • Tur pozitsiyasidagi typeof ni JavaScript'ning typeof operatoridan farqlaysiz.
  • keyof ni qiymatdan olingan turlar bilan birga ishlatasiz.
  • Indexed access (T["price"], T[K], ichma-ich T["items"][number]) bilan maydon turlarini olasiz.
  • as const massiv va obyektdan union yasaysiz — "bitta haqiqat manbai".
  • any qiymatdan tur chiqarish tuzog'ini taniysiz.

Oldin bilishingiz kerak: Function overload va this turi, Generic cheklovlar va keyof, enum va uning muqobillari, Massiv va tuple turlari.

1. Nega bu kerak?

O'tgan darslarda turlarni qo'lda yozdik. Lekin ko'pincha qiymat allaqachon bor va tur uni takrorlaydi. «Bahor» menyusi:

ts
const MENU = {
  osh: { price: 35000, cookMinutes: 40 },
  manti: { price: 30000, cookMinutes: 45 },
  somsa: { price: 8000, cookMinutes: 30 },
};

type DishName = "osh" | "manti";

function priceOf(name: DishName): number {
  return MENU[name].price;
}
console.log(priceOf("osh")); // 35000

Jasur aka menyuga somsa qo'shdi, Sardor MENU ga yozdi — lekin DishName ni unutdi. tsc jim: priceOf("somsa") chaqirilmaguncha hech narsa demaydi, chaqirilsa esa "somsa — DishName emas" deydi, garchi somsa menyuda bo'lsa ham. Bir ma'lumot ikki joyda yozilgan — ular albatta ajralib qoladi.

Yechim — turni qiymatdan chiqarib olish: type DishName = keyof typeof MENU. Menyu o'zgarsa — tur o'zi o'zgaradi. Dasturchilar buni "bitta haqiqat manbai" (single source of truth) deyishadi.

2. Tur pozitsiyasidagi typeof

2.1 Ikki xil typeof

JavaScript'da typeof — ishlash paytidagi operator, u satr qaytaradi (typeof va turni to'g'ri aniqlash darsi):

ts
const config = { serviceRate: 0.1, currency: "so'm" };
console.log(typeof config); // object

TypeScript'da esa typeof tur yozilgan joyda ham ishlatiladi — u o'zgaruvchining TypeScript turini beradi:

ts
const config = { serviceRate: 0.1, currency: "so'm" };
type Config = typeof config;

const test: Config = { serviceRate: 0.15, currency: "so'm" };
console.log(test.serviceRate); // 0.15

type Config = typeof config — { serviceRate: number; currency: string }. Bir so'z, ikki ma'no: qiymat yozilgan joyda (console.log(typeof x)) — JavaScript operatori, tur yozilgan joyda (type X = typeof x, : typeof x) — TypeScript operatori. Ikkinchisi JavaScript'da butunlay o'chadi.

2.2 Qiymat va tur — ikki alohida dunyo

TypeScript qiymatlar va turlarni alohida saqlaydi. Birini ikkinchisining o'rnida ishlatsangiz:

ts
type Dish = { name: string; price: number };
const d = typeof Dish;
const config = { serviceRate: 0.1 };
let c: config;

Kompilyator:

text
TS2693: 'Dish' only refers to a type, but is being used as a value here.
TS2749: 'config' refers to a value, but is being used as a type here. Did you mean 'typeof config'?
  • TS2693: "Dish faqat tur, lekin qiymat sifatida ishlatildi". JavaScript'da Dish degan narsa yo'q — u o'chirilgan.
  • TS2749: "config — qiymat, lekin tur sifatida ishlatildi. typeof config demoqchimidingiz?" TypeScript tuzatishni ham taklif qildi.

Klass ikkala dunyoda bor: class Order ham qiymat (konstruktor), ham tur (nusxa shakli). Shuning uchun let o: Order va new Order() ikkalasi ham ishlaydi (Klasslar TypeScript'da).

2.3 as const bilan — literal turlar

typeof qiymatning chiqarilgan turini beradi. Obyekt maydonlari kengaygan bo'ladi (Tur chiqarish):

Qiymat typeof natijasi
{ serviceRate: 0.1, currency: "so'm" } { serviceRate: number; currency: string }
{ … } as const { readonly serviceRate: 0.1; readonly currency: "so'm" }

Aniq qiymatlar kerak bo'lsa (holatlar, o'lchamlar) — as const. Faqat shakl kerak bo'lsa (sozlama) — oddiy obyekt.

2.4 Funksiyaning typeof i

typeof funksiyaga qo'llansa — uning to'liq imzosini beradi. Bu callback parametrlarini yozishda qulay: imzo qo'lda takrorlanmaydi.

ts
function priceWithService(price: number, rate = 0.1): number {
  return Math.round(price * (1 + rate));
}
type PriceFn = typeof priceWithService;

function applyToAll(prices: readonly number[], fn: PriceFn) {
  return prices.map((p) => fn(p));
}
const result = applyToAll([35000, 5000], priceWithService);
console.log(result); // [ 38500, 5500 ]

PriceFn — (price: number, rate?: number) => number. Standart qiymatli rate turda ixtiyoriy parametr bo'lib qoldi. Endi boshqa narx funksiyasi ham shu "qolip"ga tekshiriladi:

ts
function priceWithService(price: number, rate = 0.1): number {
  return Math.round(price * (1 + rate));
}
const wrong: typeof priceWithService = (p: string) => p.length;

Kompilyator:

text
TS2322: Type '(p: string) => number' is not assignable to type '(price: number, rate?: number) => number'.
  Types of parameters 'p' and 'price' are incompatible.
    Type 'number' is not assignable to type 'string'.

Tarjimasi: "(p: string) => number turini (price: number, rate?: number) => number turiga berib bo'lmaydi". Zanjirni pastdan o'qing: "parametrlar mos emas — number ni string ga berib bo'lmaydi". Funksiya turlari mosligi qoidasi — Funksiyalarni tiplash darsida. typeof fn ning eng mashhur qo'llanishi esa keyingi darsda: ReturnType<typeof fn> — "shu funksiya qaytaradigan tur".

Tekshirib ko'ring: let count = 5; type C = typeof count; va const count = 5; type C = typeof count; — C qanday tur?

Javob

Birinchisida number — let kengaygan turni oladi. Ikkinchisida 5 — const literal tur. typeof o'zgaruvchiga TypeScript bergan turni oladi, uning ichidagi qiymatni emas.

3. keyof typeof: qiymatdan kalitlar

3.1 Juftlik

Generic cheklovlar va keyof darsida keyof turdan kalitlar union'ini olardi. Qiymatdan olish uchun ikkalasi birga ishlatiladi:

ts
const MENU = {
  osh: { price: 35000, cookMinutes: 40 },
  manti: { price: 30000, cookMinutes: 45 },
  somsa: { price: 8000, cookMinutes: 30 },
};

type DishName = keyof typeof MENU;

function priceOf(name: DishName): number {
  return MENU[name].price;
}
console.log(priceOf("somsa")); // 8000

O'ngdan chapga o'qing: typeof MENU — menyu obyektining turi, keyof — uning kalitlari: "osh" | "manti" | "somsa". Endi menyuga taom qo'shilsa, DishName o'zi kengayadi. Olib tashlansa — eski nomni ishlatgan har bir joy tsc xatosi beradi.

Qavslarga e'tibor bering: keyof typeof MENU qavssiz to'g'ri o'qiladi — keyof (typeof MENU). enum muqobillari darsidagi (typeof X)[keyof typeof X] qolipining ikkinchi yarmi — aynan shu.

3.2 Index signature'da keyof

Kalitlari noma'lum lug'atda keyof aniq ro'yxat bera olmaydi:

Tur keyof
{ osh: number; manti: number } "osh" | "manti"
{ [k: string]: number } string | number
{ [n: number]: string } number

Ikkinchi qatordagi number ajablanarli ko'rinadi. Sababi Index signature va Record darsida: JavaScript son kalitni satrga aylantiradi (obj[1] = obj["1"]), shuning uchun satr imzosi son bilan murojaatga ham ruxsat beradi.

4. Indexed access: T["kalit"]

4.1 Bitta maydonning turi

Obyekt turidan bitta maydonning turini olish — qiymatlardagi obj["price"] ning tur darajasidagi aksi:

ts
type Dish = { name: string; price: number; cookMinutes: number };
type Price = Dish["price"];

const lagmon: Price = 28000;
console.log(lagmon); // 28000

Dish["price"] — indexed access type (indeks bo'yicha tur): number. Nega number deb yozmaslik kerak? Ertaga narxlar bigint yoki { amount: number; currency: string } bo'lsa, Dish["price"] ishlatilgan hamma joy avtomatik yangilanadi.

vazifalar da aynan shunday qator bor (paket.ts):

ts
const PAKET_VERSIYASI: Paket["versiya"] = 1;

Paket turida versiya: 1 (literal tur). PAKET_VERSIYASI uning turini oladi — tur o'zgarsa (versiya: 2), bu qator TS2322 bilan "qiymatni ham yangilang" deydi. 12-qismda JSDoc'da /** @type {Paket["versiya"]} */ deb yozilgan edi — sintaksis bir xil.

4.2 Union kalit va T[keyof T]

Kalit o'rnida union ham bo'lishi mumkin — natija ham union bo'ladi:

Yozuv Natija
Dish["name"] string
Dish["name" | "price"] string | number
Dish[keyof Dish] string | number — hamma qiymatlar turi

T[keyof T] — "T ning qiymatlari union'i". Bu (typeof X)[keyof typeof X] qolipining umumiy shakli.

4.3 Xatolar

ts
type Dish = { name: string; price: number };
type P = Dish["narx"];
const key = "price";
type Q = Dish[key];

Kompilyator:

text
TS2339: Property 'narx' does not exist on type 'Dish'.
TS2538: Type 'key' cannot be used as an index type.
TS2749: 'key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?
  • TS2339 — "Dish turida narx xususiyati yo'q". Oddiy: bunday maydon yo'q.
  • TS2538 — "key ni indeks turi sifatida ishlatib bo'lmaydi", TS2749 — "key qiymat, lekin tur o'rnida ishlatildi". Ikkalasi bitta xato: kvadrat qavs ichida tur kerak, key esa qiymat. Tuzatish — Dish[typeof key]: key — const, uning turi "price", natija — number.

4.4 Ichma-ich: Order["items"][number]

Indexed access zanjir bo'lib ham yoziladi. Massiv elementining turi uchun maxsus kalit — number:

ts
type Order = {
  id: number;
  items: { dish: string; qty: number }[];
};

type Item = Order["items"][number];
type ItemDish = Order["items"][number]["dish"];

const line: Item = { dish: "Osh", qty: 2 };
const name: ItemDish = "Manti";
console.log(line.qty, name); // 2 Manti

Kompilyator zanjirni chapdan o'ngga, bir bo'g'indan hisoblaydi:

Qadam Nima bo'ldi? Natija
1 Order["items"] — items maydonining turi { dish: string; qty: number }[]
2 [number] — istalgan raqamli indeksdagi element { dish: string; qty: number }
3 ["dish"] — elementning dish maydoni string

Bu turni server javobidan olinganda ayniqsa foydali: katta javob turi bir marta yoziladi, qismlari esa undan "kesib" olinadi.

Bu chiqarishni chizmada ko'ramiz:

flowchart LR
  A["const MENU = {…}"] -- "typeof" --> B["typeof MENU"]
  B -- "keyof" --> C["DishName<br/>'osh' | 'manti' | …"]
  B -- "[DishName]" --> D["MenuEntry<br/>{ price; cookMinutes }"]
  D -- "['price']" --> E["number"]

Chap tomonda — bitta qiymat. Qolgan hamma turlar undan chiqarilgan, hech biri qo'lda takrorlanmagan.

Tekshirib ko'ring: type Guest = { name: string; phones: string[] } uchun Guest["phones"][number] va Guest["phones"] turlari qanday?

Javob

Guest["phones"] — string[] (massiv), Guest["phones"][number] — string (bitta element). [number] "massivdan bitta elementga tushish" degani.

5. (typeof SIZES)[number]: massivdan union

5.1 Ro'yxat — bitta manba

enum va uning muqobillari darsida bu qolipni ko'rgandik, endi uni qismlarga ajrata olasiz:

ts
const SIZES = ["kichik", "o'rta", "katta"] as const;
type Size = (typeof SIZES)[number];

function isSize(text: string): text is Size {
  return SIZES.some((s) => s === text);
}
console.log(isSize("katta"), isSize("XL")); // true false
  • typeof SIZES — readonly ["kichik", "o'rta", "katta"] (as const tufayli tuple).
  • [number] — istalgan indeksdagi element: "kichik" | "o'rta" | "katta".

Aniq indeks ham mumkin: (typeof SIZES)[0] — "kichik". as const siz esa typeof SIZES — string[], [number] — oddiy string: union yo'qoladi.

ts
const SIZES = ["kichik", "o'rta", "katta"] as const;
const s: (typeof SIZES)[number] = "XL";

Kompilyator:

text
TS2322: Type '"XL"' is not assignable to type '"katta" | "kichik" | "o'rta"'.

Tarjimasi: ""XL" turini uch o'lcham union'iga berib bo'lmaydi". Union a'zolari xabarda alifbo tartibida — ma'nosi o'sha.

5.2 Obyekt qiymatlaridan union

Massivda [number] bo'lsa, as const obyektda qiymatlar union'i [keyof typeof X] bilan olinadi. Ikkalasini yonma-yon qo'yamiz:

Manba Qolip Natija
["S", "M"] as const (typeof X)[number] "S" | "M"
{ Small: "S", Medium: "M" } as const (typeof X)[keyof typeof X] "S" | "M"
{ Small: "S", Medium: "M" } as const keyof typeof X "Small" | "Medium"

Ro'yxat kerak bo'lsa (tugmalar, <select>) — massiv. Nom bilan murojaat kerak bo'lsa (SIZE.Small, enum o'rnida) — obyekt. Ikkala holatda ham tur qiymatdan chiqariladi va qo'lda takrorlanmaydi.

Tekshirib ko'ring: const ROLES = ["egasi", "oshpaz", "ofitsiant"] as const; — (typeof ROLES)[number] va (typeof ROLES)["length"] turlari qanday?

Javob

(typeof ROLES)[number] — "egasi" | "oshpaz" | "ofitsiant". (typeof ROLES)["length"] — 3: tuple uzunligi literal tur, length ham oddiy maydon kabi indexed access bilan olinadi.

5.3 Qavslar

typeof SIZES[number] (qavssiz) ham ishlaydi — TypeScript uni (typeof SIZES)[number] deb o'qiydi. Lekin o'quvchi uchun noaniq: "SIZES[number] ning turimi?" Shuning uchun Prettier va ko'p jamoalar qavsni yozadi. Biz ham shunday yozamiz.

6. TypeScript ushlamaydigan tuzoq: any dan chiqarilgan tur

Tur chiqarish qiymat qanday bo'lsa, shunday tur beradi. Qiymat any bo'lsa-chi?

ts
const sample = JSON.parse('{"total": 63000}');
type Order = typeof sample;

const order: Order = { totl: 1 };
console.log(order.total.toFixed(0));

tsc — xatosiz. Node esa:

text
TypeError: Cannot read properties of undefined (reading 'toFixed')

JSON.parse any qaytaradi, demak typeof sample — any, Order ham any. { totl: 1 } (harf xatosi) jim qabul qilindi, order.total ham tekshirilmadi. "Namuna JSON'dan tur yasab olish" g'oyasi shu yerda buziladi: typeof ishlash paytidagi namunani emas, tsc bilgan turni oladi.

Qoida: typeof ni faqat turi aniq qiymatlarga qo'llang — o'zingiz yozgan konstantalar, as const ro'yxatlar, sozlamalar. Tashqi ma'lumot (JSON, server, localStorage) uchun turni qo'lda yozing va ishlash paytida tekshiring (API ma'lumotlarini tiplash).

6.1 Qachon chiqarish, qachon qo'lda yozish?

Tur chiqarish kuchli, lekin har doim ham to'g'ri yo'l emas. Asosiy savol: haqiqat manbai qayerda?

  • Manba — kodning o'zidagi qiymat (menyu konstantasi, holatlar ro'yxati, sozlama). Unda turni qiymatdan chiqaring: keyof typeof MENU, (typeof SIZES)[number]. Qiymat va tur ajralib qolmaydi.
  • Manba — tashqi kelishuv (server javobi, fayl formati, boshqa jamoa API'si). Unda tur — hujjat: uni qo'lda yozing (yoki API sxemasidan avtomatik yarating), qiymat esa ishlash paytida shu turga tekshirilsin. Namuna qiymatdan chiqarilgan tur faqat bitta misolni aks ettiradi — ixtiyoriy maydonlar, null bo'lishi mumkin bo'lgan joylar unda ko'rinmaydi.
  • Manba — boshqa tur. Unda qismlarni indexed access bilan oling (Order["items"][number]), butun turni esa bir joyda saqlang.

vazifalar ham shu qoidaga amal qiladi: VazifaMalumoti (JSON shakli) — turlar.ts da qo'lda yozilgan tur, chunki u eksport fayli va server bilan kelishuv. PAKET_VERSIYASI esa shu turdan chiqarilgan (Paket["versiya"]).

7. Ko'p uchraydigan xatolar

7.1 Tur va qiymatni almashtirish

typeof Dish (tur ustida) — TS2693; let c: config (qiymat tur o'rnida) — TS2749. Tuzatish: qiymatdan tur — typeof config; turdan qiymat olib bo'lmaydi.

7.2 Indexed access'da qiymat

Dish[key] — TS2538/TS2749. Tuzatish: Dish[typeof key] yoki Dish["price"].

7.3 as const siz [number]

(typeof SIZES)[number] — string, union yo'q. Tuzatish: massiv oxirida as const.

7.4 Qiymat va turni alohida yozish

MENU va type DishName = "osh" | … — ajralib qoladi. Tuzatish: keyof typeof MENU.

7.5 any dan tur chiqarish

typeof JSON.parse(…) — any. Tuzatish: tashqi ma'lumot turini qo'lda yozing.

8. Mashqlar

1-mashq (oson): Turlarni chiqaring

ts
const TABLES = { window: 4, corner: 2, hall: 8 } as const;
type TableName = keyof typeof TABLES;
type Seats = (typeof TABLES)[TableName];
const t: TableName = "corner";
console.log(TABLES[t]); // 2

TableName da nechta a'zo bor: [:3]. (typeof TABLES)["hall"] turi (literal son): [:8]. as const siz Seats turi: .

Yechim
  • 3 ta: "window" | "corner" | "hall".
  • 8: as const qiymatlarni literal qildi.
  • number: as const siz hamma maydonlar number ga kengayadi, ularning union'i ham number.

2-mashq (o'rta): Javob turidan qismlar

Server javobining turi bitta katta tur sifatida berilgan. Undan uchta kichik turni qo'lda yozmasdan, indexed access bilan oling: bitta buyurtma (OrderRow), bitta qator (LineRow) va to'lov usuli (PayMethod).

ts
type DayReport = {
  date: string;
  orders: {
    id: number;
    lines: { dish: string; qty: number }[];
    pay: "naqd" | "karta";
  }[];
};
Yechim
ts
type DayReport = {
  date: string;
  orders: {
    id: number;
    lines: { dish: string; qty: number }[];
    pay: "naqd" | "karta";
  }[];
};

type OrderRow = DayReport["orders"][number];
type LineRow = OrderRow["lines"][number];
type PayMethod = OrderRow["pay"];

const line: LineRow = { dish: "Osh", qty: 2 };
const pay: PayMethod = "karta";
const row: OrderRow = { id: 7, lines: [line], pay };
console.log(row.lines.length, row.pay); // 1 karta
  • OrderRow — massiv elementi ([number]), LineRow — undan ham bir qavat ichkari.
  • PayMethod — "naqd" | "karta": literal union to'liq saqlandi.
  • Server javobi o'zgarsa (masalan, pay ga "click" qo'shilsa), uchala tur ham avtomatik yangilanadi.

3-mashq (qiyin): Amaliy tajriba — menyudan turlar

Mashq kurs/mashqlar/15/ papkasida. 25-qiymatdan-tur/menu.ts ni avval qo'lda yozilgan tur bilan yarating: MENU obyektida osh, manti, lag'mon va somsa (narx va pishish vaqti), type DishName = "osh" | "manti" | "lagmon" (somsa — "unutilgan") va priceOf(name: DishName). Testda priceOf("somsa") ni chaqiring. npx tsc --pretty false nima deydi?

Keyin hamma turlarni qiymatlardan chiqaring:

  • DishName — keyof typeof MENU, MenuEntry — (typeof MENU)[DishName], priceOf natijasi — MenuEntry["price"].
  • SIZES = ["kichik", "o'rta", "katta"] as const va Size — undan.
  • parseSize(text) — matndan Size (noma'lum bo'lsa TypeError); portionPrice(name, size) — kichik ×0.75, o'rta ×1, katta ×1.5, butun so'mgacha.
Yechim

Qo'lda yozilgan turda tsc 7.0.2 testni to'xtatdi:

text
25-qiymatdan-tur/menu.test.ts(7,24): error TS2345: Argument of type '"somsa"' is not assignable to parameter of type 'DishName'.

Somsa menyuda bor, lekin turda yo'q — «Nega bu kerak?» bo'limidagi ajralish.

ts
// 25-qiymatdan-tur/menu.ts — turlar qiymatlardan chiqariladi
export const MENU = {
  osh: { price: 35000, cookMinutes: 40 },
  manti: { price: 30000, cookMinutes: 45 },
  lagmon: { price: 28000, cookMinutes: 25 },
  somsa: { price: 8000, cookMinutes: 30 },
};

// Menyuga taom qo'shilsa — bu tur o'zi kengayadi
export type DishName = keyof typeof MENU;
export type MenuEntry = (typeof MENU)[DishName];

export const SIZES = ["kichik", "o'rta", "katta"] as const;
export type Size = (typeof SIZES)[number];

const SIZE_FACTORS: Record<Size, number> = {
  kichik: 0.75,
  "o'rta": 1,
  katta: 1.5,
};

export function priceOf(name: DishName): MenuEntry["price"] {
  return MENU[name].price;
}

export function parseSize(text: string): Size {
  const found = SIZES.find((s) => s === text);
  if (found === undefined) {
    throw new TypeError(`Noma'lum o'lcham: ${text}`);
  }
  return found;
}

export function portionPrice(name: DishName, size: Size): number {
  return Math.round(priceOf(name) * SIZE_FACTORS[size]);
}
ts
// 25-qiymatdan-tur/menu.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { MENU, priceOf, parseSize, portionPrice } from "./menu.ts";

test("priceOf: menyudagi har taom", () => {
  assert.equal(priceOf("somsa"), 8000);
  assert.equal(Object.keys(MENU).length, 4);
});

test("parseSize: matndan o'lcham", () => {
  assert.equal(parseSize("katta"), "katta");
  assert.throws(() => parseSize("XL"), TypeError);
});

test("portionPrice: o'lcham koeffitsiyenti bilan", () => {
  assert.equal(portionPrice("osh", "katta"), 52500);
  assert.equal(portionPrice("somsa", "kichik"), 6000);
});
  • MENU da as const yo'q — bizga taom nomlari (kalitlar) aniq kerak, narxlar esa number bo'lishi yetarli. Kalitlar as const siz ham aniq: keyof obyekt kalitlarini kengaytirmaydi.
  • SIZE_FACTORS: Record<Size, number> — o'lcham qo'shilsa, koeffitsiyentni unutib bo'lmaydi (Index signature va Record).
  • MENU[name] — name: DishName bo'lgani uchun noUncheckedIndexedAccess bilan ham undefined emas.
  • 35 000 × 1.5 = 52 500, 8 000 × 0.75 = 6 000.

npx tsc --pretty false — chiqishsiz. node --test 25-qiymatdan-tur/menu.test.ts bizda (Node 24.21.0) shunday chiqdi:

text
✔ priceOf: menyudagi har taom (1.9094ms)
✔ parseSize: matndan o'lcham (1.2068ms)
✔ portionPrice: o'lcham koeffitsiyenti bilan (0.5316ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 294.4935

XATOLAR.md ga qo'shing: TS2693, TS2749, TS2538. Keyin kurs/mashqlar papkasidan:

bash
git add 15/25-qiymatdan-tur 15/XATOLAR.md
git commit -m "15/25: menu.ts — keyof typeof va indexed access"

9. Real ishda

  • Konstantalardan turlar: marshrutlar ro'yxati, ruxsatlar, til kodlari, holatlar — as const + (typeof X)[number] yoki keyof typeof X. Kutubxonalar va katta loyihalarda eng ko'p uchraydigan qoliplardan.
  • Katta javob turlaridan qismlar: Response["data"]["items"][number] — server turi bir marta (ko'pincha avtomatik) yaratiladi, komponentlar undan kerakli qismini oladi.
  • vazifalar da: Paket["versiya"], Metric["rating"] (olchov.ts: Readonly<Record<Metric["rating"], string>> — web-vitals kutubxonasidagi baho turlaridan matnlar jadvali).
  • Keyingi qadam: ReturnType<typeof fn> — funksiya natijasidan tur (Utility types). typeof shu yerda ham asosiy rol o'ynaydi.
  • Intervyu: "typeof TypeScript'da nima qiladi?", "keyof typeof obj nima?", "Massivdan union qanday olinadi?" — juda tez-tez beriladi.

Xulosa

  • Tur pozitsiyasidagi typeof x — o'zgaruvchining TypeScript turi; JavaScript'dagi typeof (satr qaytaradi) bilan aralashtirmang.
  • Qiymat va tur — alohida dunyolar: TS2693 (tur qiymat o'rnida), TS2749 (qiymat tur o'rnida, "Did you mean 'typeof …'").
  • keyof typeof OBJ — qiymatdagi kalitlar union'i. Indexed access T["k"], T[K], T[keyof T] — maydon turlari.
  • [number] — massiv elementi: Order["items"][number], (typeof SIZES)[number] (as const bilan — union).
  • Tur faqat tsc bilgan darajada aniq: any qiymatdan chiqarilgan tur ham any.

Keyingi dars: Utility types — Partial, Pick, Omit, Record, ReturnType va boshqa tayyor tur-funksiyalar; vazifalar dagi api.ts ular bilan .ts ga o'tadi.

Manbalar

  • TypeScript Handbook: "Typeof Type Operator" — typescriptlang.org/docs/handbook/2/typeof-types.html
  • TypeScript Handbook: "Keyof Type Operator" — typescriptlang.org/docs/handbook/2/keyof-types.html
  • TypeScript Handbook: "Indexed Access Types" — typescriptlang.org/docs/handbook/2/indexed-access-types.html
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
TypeScript keyof, typeof va indexed access: turlarni qiymatlardan chiqarish — IlmHamroh