Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. Obyekt turini o'zgartiradiganlar
- 2.1 Partial<T> — hamma maydon ixtiyoriy
- 2.2 Required<T> — hamma maydon majburiy
- 2.3 Readonly<T> — hamma maydon faqat o'qish uchun
- 2.4 Pick<T, K> — faqat tanlangan maydonlar
- 2.5 Omit<T, K> — ko'rsatilganlardan tashqari hammasi
- 2.6 Record<K, V> — eslatma
- 2.7 Utility'lar birga: maydon turini almashtirish
- 3. Omit tuzog'i: kalit tekshirilmaydi
- 4. Union'ni filtrlaydiganlar
- 4.1 Exclude va Extract
- 4.2 NonNullable<T> — null va undefined siz
- 5. Funksiya va klassdan tur olish
- 5.1 ReturnType va Parameters
- 5.2 Awaited — Promise ichidagi tur
- 5.3 InstanceType — klass nusxasining turi
- 5.4 Hammasi bir jadvalda
- 5.5 Ular qanday yozilgan — bir nazar
- 6. TypeScript ushlamaydigan tuzoq: Partial va spread
- 7. Ko'p uchraydigan xatolar
- 7.1 Variant turlarni qo'lda nusxalash
- 7.2 Omit da harf xatosi
- 7.3 Exclude ni obyektga qo'llash
- 7.4 ReturnType<fn> (typeof siz)
- 7.5 Partial + spread va undefined
- 8. Mashqlar
- 1-mashq (oson): Utility'ni tanlang
- 2-mashq (o'rta): Holatlar union'idan
- 3-mashq (qiyin): Buyurtma turlari bitta manbadan
- 4-mashq: Vazifalar qadami — api.ts
- 9. Real ishda
- Xulosa
- Manbalar
TypeScript utility types: Partial, Pick, Omit, ReturnType va boshqalar
Qisqacha: Utility types — TypeScript'ning tayyor "tur-funksiyalari": mavjud turdan yangisini yasaydi.
Partial<Dish>— hamma maydon ixtiyoriy,Pick<Dish, "name">— faqat tanlangan maydonlar,Omit<Dish, "id">— ko'rsatilganlardan tashqari hammasi,ReturnType<typeof fn>— funksiya natijasining turi. Bitta asosiy tur yoziladi, uning variantlari esa undan chiqariladi.
Bu darsda
- Obyekt turini o'zgartiradigan utility'lar:
Partial,Required,Readonly,Pick,Omit,Record. - Union'ni filtrlaydiganlar:
Exclude,Extract,NonNullable. - Funksiya va klassdan tur oladiganlar:
ReturnType,Parameters,Awaited,InstanceType. Omitning kalit tekshirmasligi vaPartial+ spread tuzog'ini bilasiz.vazifalardagiapi.tsni so'rov tanalari utility types bilan yozilgan holda.tsga ko'chirasiz.
Oldin bilishingiz kerak: keyof, typeof va indexed access, Generic interface, type va klass, Index signature va Record, Union va literal turlar.
1. Nega bu kerak?
O'tgan darsda turlarni qiymatlardan chiqardik. Endi turlarni boshqa turlardan yasaymiz. «Bahor» serverida taom bilan uch xil ish bor:
- yaratish (POST):
idni server beradi, demak tanadaidyo'q; - yangilash (PATCH): istalgan maydon kelishi mumkin, hammasi ixtiyoriy;
- ro'yxat (GET): faqat nom va narx kerak.
Sardor uchala turni qo'lda yozdi:
type Dish = { id: number; name: string; price: number };
type NewDish = { name: string; price: number };
type DishPatch = { name?: string; price?: number };
type DishRow = { name: string; price: number };
const patch: DishPatch = { price: 37000 };
console.log(patch); // { price: 37000 }To'rtta tur — bitta ma'lumotning to'rt nusxasi. Ertaga Dish ga cookMinutes qo'shilsa, qolgan uchtasini ham yangilash kerak. Biri unutiladi — va server bilan kelishuv jim buziladi. Utility types bu nusxalarni formula bilan almashtiradi: NewDish = Omit<Dish, "id">.
2. Obyekt turini o'zgartiradiganlar
2.1 Partial<T> — hamma maydon ixtiyoriy
type Dish = { id: number; name: string; price: number };
type DishPatch = Partial<Dish>;
function describePatch(patch: DishPatch): string {
return Object.keys(patch).join(", ");
}
console.log(describePatch({ price: 37000 })); // pricePartial<Dish> — { id?: number; name?: string; price?: number }. PATCH so'rovi, forma qoralamasi, sozlamalarni qisman yangilash — tabiiy joylari. Partial — "qisman".
2.2 Required<T> — hamma maydon majburiy
Teskarisi: ixtiyoriy maydonlarni majburiy qiladi. Masalan, sozlamalar ixtiyoriy keladi, lekin standart qiymatlar qo'shilgach — hammasi bor bo'lishi kerak:
type Settings = { tip?: number; currency?: string };
const full: Required<Settings> = { tip: 0.1 };Kompilyator:
TS2741: Property 'currency' is missing in type '{ tip: number; }' but required in type 'Required<Settings>'.Tarjimasi: "currency xususiyati { tip: number; } da yo'q, lekin Required<Settings> da majburiy". Required ? belgilarini olib tashladi — endi currency ham bo'lishi shart.
2.3 Readonly<T> — hamma maydon faqat o'qish uchun
type Dish = { id: number; name: string; price: number };
const osh: Readonly<Dish> = { id: 1, name: "Osh", price: 35000 };
osh.price = 30000;Kompilyator:
TS2540: Cannot assign to 'price' because it is a read-only property.Tarjimasi: "price ga yozib bo'lmaydi, chunki u faqat o'qish uchun".
vazifalar dagi boshMatnlar: Readonly<Record<Filtr, string>> — ikkita utility ichma-ich (Index signature va Record darsida ko'rgandik). Readonly ham sayoz: ichki massiv va obyektlar o'zgaruvchan qoladi (Klasslar TypeScript'da darsidagi readonly kabi).
2.4 Pick<T, K> — faqat tanlangan maydonlar
type Dish = {
id: number;
name: string;
price: number;
cookMinutes: number;
};
type DishRow = Pick<Dish, "name" | "price">;
const row: DishRow = { name: "Manti", price: 30000 };
console.log(row); // { name: 'Manti', price: 30000 }Pick — "tanlab olish": K — kalitlar union'i. Ortiqcha maydon berilsa — odatdagi ortiqcha xususiyat tekshiruvi:
type Dish = { id: number; name: string; price: number };
type DishRow = Pick<Dish, "name" | "price">;
const row: DishRow = { name: "Osh", price: 1, id: 1 };Kompilyator:
TS2353: Object literal may only specify known properties, and 'id' does not exist in type 'DishRow'.Tarjimasi: "Obyekt literalida faqat ma'lum xususiyatlar bo'lishi mumkin, id esa DishRow turida yo'q" — Pick uni olmagan edi.
2.5 Omit<T, K> — ko'rsatilganlardan tashqari hammasi
type Dish = { id: number; name: string; price: number };
type NewDish = Omit<Dish, "id">;
const fresh: NewDish = { name: "Somsa", price: 8000 };
console.log(fresh.name); // SomsaOmit — "tashlab ketish". Pick ga teskari: maydonlar ko'p, olib tashlanadigani oz bo'lsa — Omit qulayroq.
2.6 Record<K, V> — eslatma
Index signature va Record darsida to'liq ko'rgandik: Record<"osh" | "manti", number> — har kalitga qiymat. U ham utility type — shu oilaning a'zosi.
2.7 Utility'lar birga: maydon turini almashtirish
Kengaytirish va kesishma darsida bola tur ota maydonining turini o'zgartira olmasligini ko'rdik (TS2430). Va'da qilingan yechim — Omit va kesishma:
type MenuItem = { name: string; price: number };
type PrintedItem = Omit<MenuItem, "price"> & { price: string };
function toPrinted(item: MenuItem): PrintedItem {
return { ...item, price: `${item.price} so'm` };
}
const printed = toPrinted({ name: "Osh", price: 35000 });
console.log(printed.price); // 35000 so'mOmit eski price ni olib tashladi, & yangisini qo'shdi. Natija: { name: string; price: string } — chek uchun narx satr ko'rinishida. Utility'lar shunday birlashadi: Partial<Pick<…>>, Readonly<Record<…>>, Omit<…> & {…}. Har biri bitta kichik o'zgarish qiladi, birga esa kerakli shaklni beradi.
Tekshirib ko'ring:
type T = Partial<Pick<Dish, "name" | "price">>—Tga{}mos keladimi?{ id: 1 }chi?
Javob
{} — mos: Pick ikki maydonni oldi, Partial ularni ixtiyoriy qildi. { id: 1 } — mos emas: id Pick da tanlanmagan, ortiqcha xususiyat tekshiruvi TS2353 beradi.
3. Omit tuzog'i: kalit tekshirilmaydi
Pick da noto'g'ri kalit yozib ko'ramiz:
type Dish = { id: number; name: string; price: number };
type Row = Pick<Dish, "prise">;Kompilyator:
TS2344: Type '"prise"' does not satisfy the constraint 'keyof Dish'.Tarjimasi: ""prise" turi keyof Dish cheklovini qanoatlantirmaydi". Pick ning ta'rifida K extends keyof T bor (Generic cheklovlar) — xato kalit ushlandi. Endi Omit:
type Dish = { id: number; name: string; price: number };
type NoPrice = Omit<Dish, "prise">;
const d: NoPrice = { id: 1, name: "Osh", price: 35000 };
console.log(d.price); // 35000tsc — xatosiz! Kompilyator bu yozuvni shunday ochadi (Omit ning ichki ta'rifi «Ular qanday yozilgan» bo'limida):
| Qadam | Nima bo'ldi? | Natija |
|---|---|---|
| 1 | keyof Dish |
"id" | "name" | "price" |
| 2 | Undan "prise" olib tashlandi — u yerda yo'q edi |
o'zgarmadi: "id" | "name" | "price" |
| 3 | Shu kalitlar tanlandi (Pick) |
{ id: number; name: string; price: number } |
Omit ning kalit parametri keyof T bilan emas, istalgan kalit bilan cheklangan. "prise" — Dish da yo'q kalit, uni "olib tashlash" hech narsa qilmadi va price joyida qoldi. Biz narxsiz tur yasadik deb o'ylaymiz, aslida esa u o'zgarmagan.
Qoida: Omit dan keyin natija turini hover'da bir marta tekshiring. Yoki muhim joylarda Pick ni afzal ko'ring — u kalitlarni tekshiradi.
4. Union'ni filtrlaydiganlar
4.1 Exclude va Extract
Bu ikkisi obyekt emas, union bilan ishlaydi:
type Status = "yangi" | "tayyorlanmoqda" | "tayyor" | "bekor";
const active: Exclude<Status, "bekor"> = "bekor";
const done: Extract<Status, "tayyor" | "berildi"> = "yangi";Kompilyator:
TS2322: Type '"bekor"' is not assignable to type '"tayyor" | "tayyorlanmoqda" | "yangi"'.
TS2322: Type '"yangi"' is not assignable to type '"tayyor"'.Exclude<Status, "bekor">— "Statusdan"bekor"ni olib tashla":"yangi" | "tayyorlanmoqda" | "tayyor".Extract<Status, "tayyor" | "berildi">— "Statusdan faqat ikkinchi union'da ham borlarini qoldir":"tayyor"."berildi"Statusda yo'q — e'tiborsiz qoldi.
Tarjimasi: birinchisi — ""bekor" ni qolgan uch holat union'iga berib bo'lmaydi", ikkinchisi — ""yangi" ni "tayyor" ga berib bo'lmaydi". Farqni eslab qolish oson: Omit/Pick — obyekt maydonlari uchun, Exclude/Extract — union a'zolari uchun.
4.2 NonNullable<T> — null va undefined siz
type MaybeName = string | null | undefined;
const name: NonNullable<MaybeName> = null;Kompilyator:
TS2322: Type 'null' is not assignable to type 'string'.Tarjimasi: "null ni string ga berib bo'lmaydi" — NonNullable dan keyin faqat string qoldi. NonNullable<string | null | undefined> — string. null va undefined darsidagi toraytirishning tur darajasidagi shakli. vazifalar ning api.ts ida aniq shunday qo'llanish bor — «Vazifalar qadami» mashqida ko'rasiz.
5. Funksiya va klassdan tur olish
5.1 ReturnType va Parameters
O'tgan darsda typeof fn funksiyaning to'liq imzosini berardi. Undan qismlarni olish:
function makeOrder(table: number, dishes: string[]) {
return { table, dishes, total: 0 };
}
type Order = ReturnType<typeof makeOrder>;
type OrderArgs = Parameters<typeof makeOrder>;
const args: OrderArgs = [7, ["Osh", "Ko'k choy"]];
const order: Order = makeOrder(...args);
console.log(order.table, order.dishes.length); // 7 2ReturnType<typeof makeOrder>—{ table: number; dishes: string[]; total: number }. Funksiya natija turi yozilmagan — TypeScript chiqargan, biz esa uni nom bilan oldik.Parameters<typeof makeOrder>—[table: number, dishes: string[]]— parametrlar tuple'i.
Eng ko'p uchraydigan holat: kutubxona funksiya eksport qiladi, lekin uning natija turini eksport qilmaydi. ReturnType uni "qo'lga oladi".
5.2 Awaited — Promise ichidagi tur
async funksiyaning natijasi — Promise. Ichidagi turni olish:
type Dish = { name: string; price: number };
async function loadMenu(): Promise<Dish[]> {
return [];
}
const menu: Awaited<ReturnType<typeof loadMenu>> = 5;Kompilyator:
TS2322: Type 'number' is not assignable to type 'Dish[]'.Tarjimasi: "number ni Dish[] ga berib bo'lmaydi". Demak Awaited<ReturnType<…>> haqiqatan Dish[] bo'ldi. ReturnType<typeof loadMenu> — Promise<Dish[]>, Awaited<…> uni ochadi — Dish[]. await operatorining tur darajasidagi aksi.
5.3 InstanceType — klass nusxasining turi
class Queue {
items: string[] = [];
}
type QueueObject = InstanceType<typeof Queue>;
const q: QueueObject = 5;Kompilyator:
TS2322: Type 'number' is not assignable to type 'Queue'.Tarjimasi: "number ni Queue ga berib bo'lmaydi" — InstanceType natijasi klass nusxasining turi ekan. typeof Queue — klassning o'zi (konstruktor), InstanceType<…> — new dan chiqadigan nusxa. Odatda klass nomining o'zi (Queue) yetadi. InstanceType klass dinamik keladigan generic kodda kerak: function create<C extends new () => object>(cls: C): InstanceType<C>.
5.4 Hammasi bir jadvalda
| Utility | Nima qiladi | Misol natija |
|---|---|---|
Partial<T> / Required<T> |
hamma maydon ? / majburiy |
{ price?: number } |
Readonly<T> |
hamma maydon readonly |
{ readonly price: number } |
Pick<T, K> / Omit<T, K> |
maydonlarni tanlash / tashlash | { name; price } |
Record<K, V> |
kalitlarga qiymat | { osh: number; … } |
Exclude<U, X> / Extract<U, X> |
union a'zolarini olib tashlash / qoldirish | "yangi" | "tayyor" |
NonNullable<T> |
null/undefined siz |
string |
ReturnType / Parameters |
funksiya natijasi / parametrlari | { … } / [a, b] |
Awaited<T> |
Promise ichidagi tur | Dish[] |
InstanceType<C> |
klass nusxasi turi | Queue |
5.5 Ular qanday yozilgan — bir nazar
Bularning hammasi sehr emas — TypeScript'ning lib.es5.d.ts faylida oddiy tur sifatida yozilgan. Masalan, Partial va Pick:
type Partial<T> = {
[P in keyof T]?: T[P];
};
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};Hozir bu yozuvni to'liq tushunish shart emas. Lekin tanish qismlarni ko'ring: keyof T va T[P] — keyof va indexed access, K extends keyof T — generic cheklov. Shu cheklov tufayli Pick noto'g'ri kalitga TS2344 berdi. Omit esa shunday yozilgan: type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>> — keyof any "istalgan kalit" degani, shuning uchun u harf xatosini ko'rmaydi. [P in …] esa yangi: "har bir kalit bo'ylab aylanib, yangi maydon yasa". Bu — mapped type, uni Mapped types darsida o'rganasiz. Exclude, ReturnType esa conditional types bilan yozilgan (Conditional types). O'sha darslardan keyin bu jadvaldagi har bir utility'ni o'zingiz qayta yoza olasiz.
Tekshirib ko'ring:
function getUser(id: number) { return { id, name: "Malika" }; }—getUsernatijasi turini qanday olasiz? Uningnamemaydoni turi-chi?
Javob
ReturnType<typeof getUser> — { id: number; name: string }. name maydoni turi — ReturnType<typeof getUser>["name"], ya'ni string (indexed access utility natijasiga ham qo'llanadi).
Tekshirib ko'ring:
type T = Exclude<"osh" | "manti" | "somsa", "somsa" | "lagmon">—Tqanday?
Javob
"osh" | "manti". "somsa" olib tashlandi, "lagmon" esa birinchi union'da yo'q edi — Exclude unga e'tibor bermaydi.
6. TypeScript ushlamaydigan tuzoq: Partial va spread
Partial — PATCH uchun qulay. Yangilashni spread bilan qo'llaymiz:
type Dish = { name: string; price: number };
function update(dish: Dish, patch: Partial<Dish>): Dish {
return { ...dish, ...patch };
}
const base = { name: "Osh", price: 35000 };
const osh = update(base, { price: undefined });
console.log(osh.price.toFixed(0));tsc — xatosiz. Node esa:
TypeError: Cannot read properties of undefined (reading 'toFixed')price?: number odatiy sozlamada "price yo'q yoki undefined" degani. { price: undefined } ruxsat etildi. Spread esa undefined ni ham yozadi — eski narx o'chdi. Funksiya natijasi Dish deb e'lon qilingan, lekin price — undefined.
Himoya — exactOptionalPropertyTypes bayrog'i: "ixtiyoriy maydon yo'q bo'lishi mumkin, lekin undefined ga teng bo'lishi mumkin emas":
// @ts-options: {"exactOptionalPropertyTypes": true}
type Dish = { name: string; price: number };
function update(dish: Dish, patch: Partial<Dish>): Dish {
return { ...dish, ...patch };
}
const base = { name: "Osh", price: 35000 };
const osh = update(base, { price: undefined });Kompilyator:
TS2379: Argument of type '{ price: undefined; }' is not assignable to parameter of type 'Partial<Dish>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Types of property 'price' are incompatible.
Type 'undefined' is not assignable to type 'number'.Tarjimasi: "{ price: undefined; } argumentini exactOptionalPropertyTypes: true bo'lganda Partial<Dish> parametriga berib bo'lmaydi. undefined ni maqsad xususiyatlari turiga qo'shishni o'ylab ko'ring". Pastki qatorlar sababni aytadi: price ga undefined emas, faqat son yoki umuman yo'qligi mumkin. Bu bayroq strict ga kirmaydi. tsc --init (TypeScript 7) uni yoqadi, vazifalar esa Strict bayroqlar oilasi qadamida yoqadi. Serverdan kelgan PATCH tanasida esa bayroq ham yordam bermaydi — u ishlash paytida tekshiriladi.
7. Ko'p uchraydigan xatolar
7.1 Variant turlarni qo'lda nusxalash
NewDish, DishPatch — Dish dan ajralib qoladi. Tuzatish: Omit<Dish, "id">, Partial<Dish>.
7.2 Omit da harf xatosi
Omit<Dish, "prise"> — jim, hech narsa olib tashlanmaydi. Tuzatish: hover'da tekshiring yoki Pick ishlating.
7.3 Exclude ni obyektga qo'llash
Exclude<Dish, "id"> — maydonni olib tashlamaydi (Dish union emas). Tuzatish: obyekt maydonlari uchun Omit.
7.4 ReturnType<fn> (typeof siz)
ReturnType<makeOrder> — TS2749: 'makeOrder' refers to a value…. Tuzatish: ReturnType<typeof makeOrder>.
7.5 Partial + spread va undefined
Natija turi yolg'on gapiradi. Tuzatish: exactOptionalPropertyTypes yoki undefined qiymatlarni spread'dan oldin tozalash.
8. Mashqlar
1-mashq (oson): Utility'ni tanlang
type Guest = { id: number; name: string; tel: string; vip: boolean };
type GuestForm = Omit<Guest, "id">;
type GuestCard = Pick<Guest, "name" | "vip">;
const card: GuestCard = { name: "Malika", vip: true };
console.log(Object.keys(card).length); // 2GuestForm da nechta maydon bor: [:3]. Hamma maydoni ixtiyoriy Guest qaysi utility bilan yasaladi: [:Partial]. Exclude<"id" | "name", "id">: .
Yechim
- 3 ta:
name,tel,vip—idolib tashlandi. Partial<Guest>."name": union'dan"id"olib tashlandi.
2-mashq (o'rta): Holatlar union'idan
type Status =
"yangi" | "tayyorlanmoqda" | "tayyor" | "berildi" | "bekor";Uchta tur yasang, union'ni qayta yozmasdan: KitchenStatus — oshxona ekranida ko'rinadiganlar ("berildi" va "bekor" siz); FinalStatus — yakuniy holatlar ("berildi" va "bekor"); isFinal(s: Status): s is FinalStatus — tur predikati.
Yechim
type Status =
"yangi" | "tayyorlanmoqda" | "tayyor" | "berildi" | "bekor";
type FinalStatus = Extract<Status, "berildi" | "bekor">;
type KitchenStatus = Exclude<Status, FinalStatus>;
function isFinal(s: Status): s is FinalStatus {
return s === "berildi" || s === "bekor";
}
const board: KitchenStatus[] = ["yangi", "tayyorlanmoqda", "tayyor"];
console.log(board.length); // 3
console.log(isFinal("berildi"), isFinal("tayyor")); // true falseKitchenStatusFinalStatusdan yasaldi — yakuniy holat qo'shilsa, ekran turidan o'zi chiqib ketadi.isFinal— tur predikati:trueshoxidas—FinalStatus,falseshoxida —KitchenStatus.
3-mashq (qiyin): Buyurtma turlari bitta manbadan
Order turidan uchta tur va uchta funksiya yasang: NewOrder (yaratish — id va createdAt siz), OrderPatch (faqat table va items, ixtiyoriy), OrderSummary (id va total). createOrder(data), applyPatch(order, patch) (asl buyurtma o'zgarmasin), summarize(order). exactOptionalPropertyTypes yoqilgan bo'lsin.
Yechim
// @ts-options: {"exactOptionalPropertyTypes": true}
type Order = {
readonly id: number;
table: number;
items: string[];
total: number;
createdAt: string;
};
type NewOrder = Omit<Order, "id" | "createdAt">;
type OrderPatch = Partial<Pick<Order, "table" | "items">>;
type OrderSummary = Pick<Order, "id" | "total">;
let nextId = 100;
function createOrder(data: NewOrder): Order {
return { ...data, id: nextId++, createdAt: "2026-10-06T12:00" };
}
function applyPatch(order: Order, patch: OrderPatch): Order {
return { ...order, ...patch };
}
function summarize(order: Order): OrderSummary {
return { id: order.id, total: order.total };
}
const o = createOrder({ table: 7, items: ["Osh"], total: 35000 });
const moved = applyPatch(o, { table: 3 });
console.log(summarize(moved), moved.table, o.table);Konsolda:
{ id: 100, total: 35000 } 3 7Partial<Pick<…>>— ikki utility ichma-ich: avval tanlash, keyin ixtiyoriy qilish.applyPatchspread bilan yangi obyekt qaytaradi —o.table7 qoldi.exactOptionalPropertyTypestufayli{ table: undefined }berib bo'lmaydi.summarize—Orderga ortiqcha maydon qo'shilsa hamOrderSummaryo'zgarmaydi: u faqat kerakli ikki maydonni oladi.
4-mashq: Vazifalar qadami — api.ts
api.js (11-qismdan beri — server bilan gaplashadigan yagona modul) .ts ga o'tadi. So'rov tanalari VazifaMalumoti dan utility types bilan yasaladi.
- Branch:
refactor/api-utility-types - Commit:
refactor: api.ts — so'rov tanalari Pick/Partial/Omit bilan, tanasi:javobniOqi any → unknown; ApiKlient = ReturnType<typeof apiKlient>
git mv assets/js/api.js assets/js/api.ts,npx tsc --noEmit— nechta xato?- So'rov tanalari:
YangiVazifa(POST — faqat matn) vaVazifaOzgarishi(PATCH —iddan boshqa maydonlar, ixtiyoriy). Klient obyektining turi —ApiKlient(funksiyadan chiqarilsin). javobniOqinatijasi JSDoc'daanyedi —unknownqiling. Xato xabarini o'qishdagimalumot?.xato—unknownbilan ishlamaydi; uni alohida funksiyaga oling.- Import yo'llari (
asosiy.js,api.test.js,api.tarmoq.js) vasw.jsdaVERSIYA = "v5-6".
Yechim
1. Nomi o'zgartirilganda — 33 ta xato:
- TS7006 (any parametr)24 xato
- TS7031 (any destructuring)4 xato
- TS2339 (yo'q xususiyat)3 xato
- TS2739 (maydonlar yo'q)1 xato
- TS7053 (any indeks)1 xato
Manba: O'lchandi: tsc 7.0.2 --noEmit, vazifalar holatlar/21 → api.ts, Node 24.21.0, 2026-10-06
Ikkitasi qiziq:
assets/js/api.ts(85,5): error TS7053: Element implicitly has an 'any' type because expression of type '"Content-Type"' can't be used to index type '{ Accept: string; }'.
Property 'Content-Type' does not exist on type '{ Accept: string; }'.
assets/js/api.ts(126,33): error TS2739: Type '{}' is missing the following properties from type '{ kutish?: number | undefined; metod?: string | undefined; signal: any; tana: any; }': signal, tanaBirinchisi: headers: { Accept: "application/json" } dan TypeScript aniq bitta kalitli tur chiqardi, keyin headers["Content-Type"] = … — yo'q kalit. Tuzatish — sarlavhalar turini lug'at deb yozish: Record<string, string>. Ikkinchisi: JSDoc'dagi @typedef lar .ts da o'qilmadi, destructuring'dan chiqarilgan tur signal va tana ni majburiy deb oldi.
2–3. Utility types bilan — api.ts ning tur qismi:
// Utility types: so'rov tanalari VazifaMalumoti'dan yasaladi — maydon
// nomi yoki turi o'zgarsa, bu yerlar ham tsc xatosi bilan eslatadi.
/** POST: yangi vazifa — faqat matn (id va holatni server beradi) */
export type YangiVazifa = Pick<VazifaMalumoti, "matn">;
/** PATCH: matn va/yoki bajarildi; id o'zgarmaydi */
export type VazifaOzgarishi = Partial<Omit<VazifaMalumoti, "id">>;
type IchkiSozlama = SorovSozlamasi & {
metod?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
tana?: unknown;
};Mana bu turlar qanday yasalgani:
flowchart LR
V["VazifaMalumoti<br/>id, matn, bajarildi"]
V -- "Pick 'matn'" --> Y["YangiVazifa<br/>matn"]
V -- "Omit 'id'" --> O["matn, bajarildi"]
O -- "Partial" --> Z["VazifaOzgarishi<br/>matn?, bajarildi?"]Bitta asosiy tur — ikkita so'rov tanasi. VazifaMalumoti ga maydon qo'shilsa, PATCH turi uni o'zi oladi.
Klient va yordamchilar:
function yoz(
yol: string,
metod: NonNullable<IchkiSozlama["metod"]>,
tana: unknown,
sozlama?: SorovSozlamasi,
) { … }
/** Klient obyektining turi — funksiyadan chiqarib olinadi */
export type ApiKlient = ReturnType<typeof apiKlient>;NonNullable<IchkiSozlama["metod"]>— indexed access ("GET" | … | undefined, chunkimetod?:ixtiyoriy) vaNonNullable(undefinedolib tashlandi). Yozuv so'rovida metod har doim aniq.ReturnType<typeof apiKlient>—apiKlient()qaytaradigan obyekt (royxat,qosh,yangila,ochir,almashtir) turini qo'lda yozmasdan oldik. Metod qo'shilsa, tur o'zi kengayadi.- Sarlavhalar:
RequestInit & { headers: Record<string, string> }—fetchsozlamasi turi va kesishma bilan "sarlavhalar — lug'at".
javobniOqi — any o'rniga unknown:
// Server xato javobida { xato: "..." } yuboradi
function serverXabari(malumot: unknown): string | undefined {
if (
typeof malumot === "object" &&
malumot !== null &&
"xato" in malumot &&
typeof malumot.xato === "string"
) {
return malumot.xato;
}
return undefined;
}JavaScript versiyasida malumot?.xato tekshiruvsiz o'tardi. Masalan, server { "xato": 42 } yuborsa, xabar o'rniga son chiqardi. Endi esa toraytirish majburiy. Funksiya javobniOqi endi unknown qaytaradi va javob shaklini chaqiruvchi tekshiradi — bu API ma'lumotlarini tiplash qadamida to'liq qilinadi. Yana bir o'zgarish: tarmoqXatosi dagi /** @type {Error} */ (xato) assertion xato instanceof Error tekshiruviga almashdi.
Turlar haqiqatan ishlaydi — vaqtinchalik faylda tekshirildi (haqiqiy tsc):
error TS2353: Object literal may only specify known properties, and 'id' does not exist in type 'Partial<Omit<VazifaMalumoti, "id">>'.
error TS2322: Type 'string' is not assignable to type 'boolean | undefined'.PATCH tanasiga id berib bo'lmaydi, bajarildi: "ha" (satr) ham o'tmaydi.
Commit va PR:
git switch -c refactor/api-utility-types
git mv assets/js/api.js assets/js/api.ts
# turlar, unknown, import yo'llari, sw.js VERSIYA
npm run build && npm test && npm run tip
npm run lint && npm run format:check
git add .
git commit -m "refactor: api.ts — so'rov tanalari Pick/Partial/Omit bilan" \
-m "javobniOqi any → unknown; ApiKlient = ReturnType<typeof apiKlient>"
git push -u origin refactor/api-utility-types
gh pr create --fill
gh pr merge --mergeCommit sarlavhasi — 60 belgi. Natija: npm test — 137/137, npm run test:tarmoq — 2/2 (haqiqiy API bilan), tip, lint, format:check — toza. Brauzer tekshiruvi (dist/) — 159/159. Diff: 6 fayl, +220 −211.
9. Real ishda
- API qatlami — utility types'ning asosiy uyi:
CreateUserDto = Omit<User, "id" | "createdAt">,UpdateUserDto = Partial<CreateUserDto>. NestJS (keyingi qismlarda) daPartialType,PickTypekabi yordamchilar aynan shu g'oyani klasslar uchun bajaradi. - Forma holati:
Partial<FormValues>— to'ldirilayotgan forma,Required<FormValues>— yuborishdan oldin tekshirilgan. - Kutubxona turlarini "qo'lga olish":
ReturnType<typeof createStore>,Parameters<typeof fetch>[1](fetch sozlamasi),Awaited<ReturnType<typeof loadUser>>— eksport qilinmagan turni olishning standart yo'li. - Intervyu: "
PickvaOmitfarqi?", "ExcludevaOmitfarqi?", "Partialni o'zingiz yozing" (javobi — Mapped types darsida) — juda tez-tez beriladi.
Xulosa
- Utility types — tayyor tur-funksiyalar: bitta asosiy tur, variantlari formula bilan (
Omit<Dish, "id">,Partial<Dish>). - Obyekt maydonlari:
Partial,Required,Readonly,Pick,Omit,Record. Union a'zolari:Exclude,Extract,NonNullable. - Funksiya va klassdan:
ReturnType,Parameters,Awaited,InstanceType—typeofbilan. Pickkalitlarni tekshiradi (TS2344),Omit— tekshirmaydi: noto'g'ri kalit jim o'tadi.Partial+ spreadundefinedni yozib yuboradi —exactOptionalPropertyTypesbuni ushlaydi.
Keyingi dars: Mapped types — { [K in keyof T]: … } bilan Partial va Readonly ni o'zingiz yozasiz, kalitlarni qayta nomlaysiz va filtrlaysiz.
Manbalar
- TypeScript Handbook: "Utility Types" — typescriptlang.org/docs/handbook/utility-types.html
- TSConfig:
exactOptionalPropertyTypes— typescriptlang.org/tsconfig#exactOptionalPropertyTypes - TypeScript 4.5 Release Notes: "The
AwaitedType" — typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!