14 β Utility types¶
β¬ οΈ Oldingi: 13 β Klasslar TypeScript'da Β· π README Β· Keyingi: 15 β Mapped va conditional types β‘οΈ
Bu bobda: mavjud tipdan qo'lda qayta yozmasdan yangi tip yasashni o'rganamiz. TypeScript bilan birga keladigan tayyor utility type (yordamchi tip) larni β
Partial<T>(hammasi ixtiyoriy),Required<T>,Readonly<T>,Pick<T, K>,Omit<T, K>,Record<K, V>(lug'at),Exclude/Extract(union filtri),NonNullable,ReturnType<F>,Parameters<F>vaAwaited<T>ni ko'rib chiqamiz. Har biri qachon kerakligini real misollarda ko'ramiz va ularni zanjirga ulashni o'rganamiz.
Muammo¶
Tasavvur qiling, sizda foydalanuvchi tipi bor:
Endi loyihada bir nechta yaqin, lekin biroz boshqacha tiplar kerak bo'ldi:
- Profilni tahrirlash formasi. Foydalanuvchi faqat bitta maydonni β masalan, emailni β yangilashi mumkin. Demak forma uchun tipda hamma maydon ixtiyoriy bo'lishi kerak (faqat email yuborilsa ham yaramli bo'lsin).
- API javobi. Frontendga faqat
idvaismqaytariladi (email, yosh β maxfiy). Demak shu yerda faqat ikki maydonli tip kerak. - Yangi foydalanuvchi yaratish.
idbazada avtomatik beriladi, shuning uchun yaratishda id'siz tip kerak.
JavaScript'da bunday holatda har bir variant uchun obyektni boshidan, qo'lda yozardingiz:
// β Qo'lda takrorlangan β har biri alohida yozildi:
type FoydalanuvchiUpdate = { id?: number; ism?: string; email?: string; yosh?: number };
type FoydalanuvchiJavob = { id: number; ism: string };
type FoydalanuvchiYangi = { ism: string; email: string; yosh: number };
Bu yerda muammo aniq: Foydalanuvchiga telefon maydoni qo'shsangiz, yuqoridagi uch joyni ham qo'lda yangilashga to'g'ri keladi. Bittasini unutsangiz β tiplar bir-biriga mos kelmay qoladi va xato sezilmay o'tib ketadi.
TypeScript bu muammoni utility types bilan hal qiladi. Utility type β bu mavjud tipni qabul qilib, undan yangi tip yasab beradigan tayyor generic vositadir (10-bobdagi type alias va 11-bobdagi generic ustiga qurilgan). Yuqoridagi uchchala tipni shunday yozsa bo'ladi:
type FoydalanuvchiUpdate = Partial<Foydalanuvchi>; // hammasi ixtiyoriy
type FoydalanuvchiJavob = Pick<Foydalanuvchi, "id" | "ism">; // faqat 2 maydon
type FoydalanuvchiYangi = Omit<Foydalanuvchi, "id">; // id'siz
Endi Foydalanuvchiga maydon qo'shsangiz β bu uch tip avtomatik yangilanadi. Bitta manba, hamma joy o'zidan o'zi mos. Mana shu β utility types kuchi. Birma-bir tanishamiz.
Partial β hammasini ixtiyoriy qilish¶
Partial<T> tipdagi har bir maydonni ixtiyoriy (? qo'shadi) qiladi. "Bu obyektning ba'zi maydonlarini berishim mumkin, hammasini emas" degan holatlar uchun.
type Foydalanuvchi = {
id: number;
ism: string;
email: string;
yosh: number;
};
// Partial<Foydalanuvchi> = { id?: number; ism?: string; email?: string; yosh?: number }
function profilYangila(id: number, ozgarishlar: Partial<Foydalanuvchi>) {
// ozgarishlar ichida faqat o'zgargan maydonlar bo'ladi
return ozgarishlar;
}
profilYangila(1, { email: "yangi@mail.uz" }); // β
faqat email
profilYangila(1, { ism: "Olim", yosh: 30 }); // β
ikkita maydon
profilYangila(1, {}); // β
hatto bo'sh obyekt ham yaramli
β
Bularning hammasi toza kompilyatsiya o'tadi. Partial tufayli "faqat o'zgartirilayotgan maydonlarni yubor" qoidasi tipda ifodalandi.
π Partial faqat mavjud maydonlarni ixtiyoriy qiladi β yangi maydon qo'shishga ruxsat bermaydi. Notanish maydon yuborsangiz, xato chiqadi:
profilYangila(1, { rang: "qora" });
// β Xato: Object literal may only specify known properties,
// and 'rang' does not exist in type 'Partial<Foydalanuvchi>'.
π‘ Partial "update" (yangilash) qolipining asosiy quroli. Qachonki obyektning bir qismini qabul qilsangiz β Partial<T> deb o'ylang.
Required β hammasini majburiy qilish¶
Required<T> β Partial'ning aksi: barcha ? belgilarni olib tashlaydi, ya'ni har bir maydon majburiy bo'ladi. Tipida ixtiyoriy maydonlar bor obyektni "endi hammasi to'ldirilgan" deb kafolatlamoqchi bo'lganda kerak.
type Sozlamalar = {
rang?: string;
shrift?: string;
hajm?: number;
};
// Required<Sozlamalar> = { rang: string; shrift: string; hajm: number }
function ishlat(s: Required<Sozlamalar>) {
return s.rang.toUpperCase(); // rang aniq string, undefined emas β bemalol
}
ishlat({ rang: "qora", shrift: "Inter", hajm: 14 }); // β
hammasi berildi
β
Toza o'tadi. Endi s.rang string | undefined emas, balki to'g'ridan-to'g'ri string β shuning uchun .toUpperCase() ni tekshiruvsiz chaqirsa bo'ladi.
Birorta maydon tushib qolsa, xato chiqadi:
const s: Required<Sozlamalar> = { rang: "qora" };
// β Xato (TS2739): Type '{ rang: string; }' is missing the following
// properties from type 'Required<Sozlamalar>': shrift, hajm
π‘ Amaliy qolip: foydalanuvchidan ixtiyoriy sozlamalarni olasiz, ularni default qiymatlar bilan to'ldirasiz va natijada Required<Sozlamalar> hosil bo'ladi β endi dastur ichida har bir maydon bor deb ishonchli foydalanasiz.
Readonly β o'zgartirishni taqiqlash¶
Readonly<T> har bir maydonni readonly qiladi β ya'ni obyektni yaratgandan keyin uning maydonlarini o'zgartirib bo'lmaydi. Tasodifiy o'zgarishlardan himoyalanish uchun.
type Hujjat = {
id: number;
matn: string;
};
const h: Readonly<Hujjat> = { id: 1, matn: "salom" };
console.log(h.matn); // β
o'qish mumkin
O'zgartirishga urinsangiz β kompilyator to'xtatadi:
π Readonly faqat eng yuqori darajadagi maydonlarni muhrlaydi β agar maydon ichida yana obyekt bo'lsa, uning ichi himoyalanmaydi ("sayoz" / shallow himoya). Chuqur himoya uchun har bir ichki tipni alohida o'rab chiqish kerak (yoki keyingi boblardagi yanada chuqurroq usullar).
π‘ readonly faqat kompilyatsiya paytida ishlaydi β tekshiruv. Tayyor JavaScript'da hech qanday himoya qolmaydi (bu 1-bobdagi "tiplar runtime'da yo'qoladi" qoidasining davomi). Ya'ni Readonly β bu sizning xatolaringizdan himoya, dushmandan emas.
Pick β kerakli maydonlarni tanlash¶
Pick<T, K> tipdan faqat siz aytgan maydonlarni oladi. K β qaysi maydonlarni olishni ko'rsatadigan kalit nomlari unioni (literal tiplar β 7-bob).
type Maqola = {
id: number;
sarlavha: string;
matn: string;
muallifId: number;
yaratilganSana: Date;
};
// Faqat ro'yxat ko'rsatish uchun: id va sarlavha yetarli
type MaqolaQisqa = Pick<Maqola, "id" | "sarlavha">;
// = { id: number; sarlavha: string }
const m: MaqolaQisqa = { id: 5, sarlavha: "TypeScript darslari" };
console.log(m.sarlavha); // β
β
Toza o'tadi. MaqolaQisqada faqat ikki maydon bor β qolganlari yo'q.
Olinmagan maydonni qo'shsangiz, xato chiqadi:
const m: MaqolaQisqa = { id: 5, sarlavha: "TS", matn: "..." };
// β Xato: Object literal may only specify known properties,
// and 'matn' does not exist in type 'MaqolaQisqa'.
π K β tipni emas, maydon nomlarini (string literal) qabul qiladi. Mavjud bo'lmagan nom yozsangiz (masalan Pick<Maqola, "narx">), TypeScript darrov ogohlantiradi: bunday maydon yo'q. Bu β Pick ning kuchi: maydon nomini xato yozsangiz ham ushlab oladi.
π‘ Pick ayniqsa API javobi uchun ajoyib: serverdagi to'liq yozuvdan frontendga ko'rsatiladigan "yengil" tipni shu bilan yasaysiz.
Omit β keraksiz maydonlarni olib tashlash¶
Omit<T, K> β Pick'ning aksi: K da sanab o'tilgan maydonlardan tashqari hammasini qoldiradi. "Shu maydonlarni olib tashla, qolgani turaversin" degani.
type Maqola = {
id: number;
sarlavha: string;
matn: string;
muallifId: number;
yaratilganSana: Date;
};
// Yangi maqola yaratish: id va sana avtomatik beriladi, qolgani foydalanuvchidan
type YangiMaqola = Omit<Maqola, "id" | "yaratilganSana">;
// = { sarlavha: string; matn: string; muallifId: number }
const ym: YangiMaqola = {
sarlavha: "Salom",
matn: "Maqola matni...",
muallifId: 1,
};
console.log(ym.matn); // β
β
Toza o'tadi. id va yaratilganSana tipdan olib tashlandi.
Pick yoki Omit β qaysi birini tanlayman? Oddiy qoida: ozini qoldirmoqchi bo'lsangiz Pick (sanab beraman, shularni ol), ko'pini qoldirmoqchi bo'lsangiz Omit (bir-ikkitasini tashla, qolgani tursin). Ikkalasi bir natijaga olib kelishi mumkin, lekin kamroq nom yozadigani odatda o'qishga qulayroq.
π Omit da olib tashlanayotgan maydon nomini xato yozsangiz, TypeScript (tarixiy sabablarga ko'ra) har doim ham ogohlantirmaydi. Shuning uchun nomlarni diqqat bilan yozing. Pick esa har doim tekshiradi β bu jihatdan Pick xavfsizroq.
Record β lug'at (kalit-qiymat) tuzish¶
Record<K, V> lug'at tipini yasaydi: K β qanday kalitlar bo'lishi mumkinligini, V β har bir qiymatning tipini belgilaydi. "Har bir kalitga shunday qiymat biriktiraman" degani.
Eng kuchli holati β kalitlar literal union bo'lganda: TypeScript har bir kalit majburiy ekanini talab qiladi.
type Rang = "qizil" | "yashil" | "kok";
// Har bir rang nomiga HEX kod biriktiramiz:
const ranglar: Record<Rang, string> = {
qizil: "#dc2626",
yashil: "#16a34a",
kok: "#2563eb",
};
console.log(ranglar.qizil); // β
"#dc2626"
β Toza o'tadi. Bironta rangni unutsangiz β xato:
const ranglar: Record<Rang, string> = {
qizil: "#dc2626",
yashil: "#16a34a",
}; // β Xato: Property 'kok' is missing in type
// '{ qizil: string; yashil: string; }'
// but required in type 'Record<Rang, string>'.
π Aynan shu β Recordning eng foydali tomoni: literal union kalitlar bilan, bironta variant qolib ketmasligi kafolatlanadi. Yangi rang qo'shsangiz, lug'atda uni to'ldirmaguningizcha kod kompilyatsiya o'tmaydi.
K o'rnida oddiy string ham ishlatsa bo'ladi β bunda kalitlar oldindan ma'lum bo'lmagan ochiq lug'at chiqadi:
type Mahsulot = { nom: string; narx: number };
// Kalit β istalgan string (mahsulot kodi), qiymat β Mahsulot:
const ombor: Record<string, Mahsulot> = {
"A1": { nom: "Olma", narx: 5000 },
"B2": { nom: "Banan", narx: 8000 },
};
console.log(ombor["A1"].nom); // β
"Olma"
β
Bu ham toza o'tadi. Record<string, Mahsulot> β "kalit string, qiymat Mahsulot bo'lgan lug'at". JavaScript'dagi oddiy obyekt-lug'atning tiplangan ko'rinishi.
π‘ Record<string, T> β koddagi "obyektni lug'at sifatida ishlataman" niyatini aniq bildiradi. { [key: string]: T } (index signature) bilan deyarli bir xil, lekin Record qisqaroq va o'qishga qulayroq.
Exclude va Extract β union'ni filtrlash¶
Bular obyekt bilan emas, union tip bilan ishlaydi (7-bob). Ikkalasi union ichidan a'zolarni saralaydi:
Exclude<T, U>βTdanUga to'g'ri keladiganlarni olib tashlaydi (chiqarib yuboradi).Extract<T, U>βTdan faqatUga to'g'ri keladiganlarni qoldiradi (ajratib oladi).
type Holat = "kutilmoqda" | "jarayonda" | "tugatildi" | "bekor";
// Tugamagan, bekor qilinmagan β ya'ni faol holatlar:
type FaolHolat = Exclude<Holat, "bekor" | "tugatildi">;
// = "kutilmoqda" | "jarayonda"
const fh: FaolHolat = "jarayonda"; // β
β
Toza o'tadi. Endi FaolHolat ga olib tashlangan a'zoni berib bo'lmaydi:
Extract esa teskari β kerakli a'zolarni ajratib oladi. Ko'pincha aralash union'dan bitta tipni sug'urib olishga ishlatiladi:
type Aralash = string | number | boolean;
type FaqatMatn = Extract<Aralash, string>; // = string
const fm: FaqatMatn = "matn"; // β
β
Toza o'tadi. Extract Aralash ichidan faqat string ga mosini qoldirdi.
π Esda saqlash uchun: Exclude = exit (chiqib ket), Extract = ajratib ol. Ikkalasi ichkarida "conditional type" (shartli tip) ustiga qurilgan β uni 15-bobda ochib beramiz. Hozircha "union filtri" deb yodda tuting.
NonNullable β null va undefined'ni olib tashlash¶
NonNullable<T> union ichidan null va undefined ni olib tashlaydi β qiymat aniq bor ekaniga ishonch hosil qilgan joylar uchun.
type MumkinBosh = string | null | undefined;
type AlbattaBor = NonNullable<MumkinBosh>; // = string
const ab: AlbattaBor = "bor"; // β
β
Toza o'tadi. Aslida bu Exclude<T, null | undefined> ning qulay, nomli ko'rinishi β lekin shu qadar tez-tez kerak bo'ladiki, TypeScript unga alohida nom bergan.
π‘ NonNullable ko'pincha boshqa utility natijasini "tozalash" uchun ishlatiladi (masalan, qiymat bo'lishi/bo'lmasligi mumkin bo'lgan tipni keyinroq aniq bor deb belgilash). Amalda, 8-bobdagi narrowing (tip toraytirish) ko'pincha bu ishni o'zi qiladi β lekin tip darajasida kerak bo'lganda NonNullable qo'l keladi.
ReturnType va Parameters β funksiyadan tip olish¶
Bu ikkisi funksiyadan tip "sug'urib oladi". Funksiya yozilgan, lekin uning kirish/chiqish tipiga alohida nom bermagansiz β mana shu yerda asqotadi.
ReturnType<F> β funksiya qaytaradigan qiymat tipini beradi. typeof bilan birga ishlatiladi (funksiyaning o'zidan emas, tipidan olish uchun):
function foydalanuvchiYarat(ism: string) {
return { id: Date.now(), ism, faol: true };
}
// Funksiya nima qaytarsa β shu tipni avtomatik olamiz:
type FoydalanuvchiNatija = ReturnType<typeof foydalanuvchiYarat>;
// = { id: number; ism: string; faol: boolean }
const fn: FoydalanuvchiNatija = { id: 1, ism: "Olim", faol: true }; // β
console.log(fn.faol);
β
Toza o'tadi. E'tibor bering: natija tipini qo'lda yozmadik. Funksiya o'zgarsa (masalan, faol o'rniga boshqa maydon qaytarsa), FoydalanuvchiNatija o'zidan o'zi yangilanadi.
π Nega typeof foydalanuvchiYarat? Chunki ReturnType tip kutadi, foydalanuvchiYarat esa qiymat (funksiyaning o'zi). typeof qiymatdan uning tipini oladi (3-bobdagi typeof tip operatori). Shuning uchun ReturnType<typeof funksiya> β deyarli har doim shu qolipda yoziladi.
Parameters<F> β funksiyaning argumentlari tiplarini tuple (4-bob) ko'rinishida beradi:
function buyurtmaYarat(mahsulotId: number, soni: number, manzil: string) {
return { mahsulotId, soni, manzil };
}
type BuyurtmaArgs = Parameters<typeof buyurtmaYarat>;
// = [mahsulotId: number, soni: number, manzil: string]
const args: BuyurtmaArgs = [10, 2, "Toshkent"]; // β
buyurtmaYarat(...args); // tuple'ni argument sifatida yoyamiz
β
Toza o'tadi. Parameters ayniqsa funksiyani o'rab (wrap qilib), uning argumentlarini o'zgartirmasdan uzatadigan joylarda foydali (masalan, logging yoki keshlash qoplamasi).
Awaited β Promise ichidan tip olish¶
Awaited<T> Promise<X> ichidan X ni chiqarib oladi β await qilingandan keyin qanday qiymat qolishini tip darajasida beradi (20-bobda Promise'larni chuqurroq ko'ramiz).
async function malumotOl(): Promise<{ ism: string }> {
return { ism: "Olim" };
}
// ReturnType -> Promise<{ ism: string }>, Awaited uni "ochadi":
type MalumotTipi = Awaited<ReturnType<typeof malumotOl>>;
// = { ism: string }
const mt: MalumotTipi = { ism: "Olim" }; // β
console.log(mt.ism);
β
Toza o'tadi. ReturnType<typeof malumotOl> o'zi Promise<{ ism: string }> beradi β bizga esa awaitdan keyingi tip kerak, shuning uchun ustiga Awaited qo'yamiz.
π Awaited "ichma-ich" Promise'larni ham ochadi: Awaited<Promise<Promise<number>>> natijasi number. Real kodda kamdan-kam uchraydi, lekin async natija tipini olishda ishonchli.
Utility'larni zanjirlash¶
Eng kuchli tomoni shundaki, utility'lar bir-birining ichiga joylanadi β natijada aynan kerakli tip chiqadi. Boshlanishdagi "forma update" muammosini eslang: yangilashda hamma maydon ixtiyoriy bo'lsin, lekin idni o'zgartirib bo'lmasin. Ikkala talabni bitta tipda ifodalaymiz:
type Talaba = {
id: number;
ism: string;
email?: string;
baho?: number;
};
// Avval id'ni olib tashla (Omit), keyin qolganini ixtiyoriy qil (Partial):
type TalabaFormaUpdate = Partial<Omit<Talaba, "id">>;
// = { ism?: string; email?: string; baho?: number }
const tu: TalabaFormaUpdate = { baho: 5 }; // β
faqat baho yangilanadi
console.log(tu.baho);
β
Toza o'tadi. Ichkaridan tashqariga o'qiladi: avval Omit<Talaba, "id"> (id'siz tip), so'ng uni Partial<...> (hammasi ixtiyoriy) o'raydi. Aynan kerakli natija β idsiz va hammasi ixtiyoriy.
π‘ Zanjir tartibi muhim: Partial<Omit<...>> va Omit<Partial<...>> ko'pincha bir xil natija bersa-da, niyatni aniq bildirish uchun "avval keraksizni tashla, keyin moslashtir" tartibi o'qishga qulayroq. Murakkab zanjirga alohida nom bering β kod hujjatga aylanadi.
Bonus: satisfies bilan tipni tekshirish¶
Zamonaviy TypeScript (4.9+) da satisfies operatori bor β u qiymat biror tipga mos kelishini tekshiradi, lekin qiymatning aniqroq (tor) tipini saqlab qoladi. Record bilan birga juda qulay:
const yollar = {
bosh: "/",
haqida: "/about",
aloqa: "/contact",
} satisfies Record<string, string>;
// yollar har bir kaliti tekshirildi (qiymati string),
// lekin kalitlar nomi ham saqlandi:
const x: string = yollar.bosh; // β
aniq mavjud kalit
console.log(x);
β
Toza o'tadi. Farqi nimada? Agar const yollar: Record<string, string> = {...} deb yozsangiz, TypeScript yollar.notogriKalit ni ham xato deb hisoblamaydi (har qanday string kalit ruxsat etilgan). satisfies esa moslikni tekshiradi-yu, lekin yollarning aniq kalitlarini (bosh, haqida, aloqa) "eslab qoladi" β shuning uchun mavjud bo'lmagan kalitga murojaat xatoni ushlaydi. Ikkala dunyoning eng yaxshisi.
Xulosa: qaysi utility qachon?¶
| Utility | Nima qiladi | Qachon kerak |
|---|---|---|
Partial<T> |
Hammasi ixtiyoriy | Yangilash (update) formasi |
Required<T> |
Hammasi majburiy | Default'lar bilan to'ldirilgan sozlama |
Readonly<T> |
O'zgartirib bo'lmaydi | Muhrlangan, o'zgarmas obyekt |
Pick<T, K> |
Faqat tanlanganlar | API javobi, yengil ko'rinish |
Omit<T, K> |
Tanlangandan boshqasi | Yaratish tipi (id'siz) |
Record<K, V> |
Kalit-qiymat lug'at | Sozlama jadvali, ko'rsatkichlar |
Exclude<T, U> |
Union'dan olib tashlash | Holatlarni filtrlash |
Extract<T, U> |
Union'dan ajratib olish | Aralashdan bitta tip |
NonNullable<T> |
null/undefined yo'q | Qiymat aniq bor |
ReturnType<F> |
Funksiya natija tipi | Tipni qo'lda yozmaslik |
Parameters<F> |
Funksiya argument tiplari | Funksiyani o'rash |
Awaited<T> |
Promise ichidagi tip | async natija tipi |
Bu utility'larning hammasi ichkarida mapped types va conditional types ustiga qurilgan β ya'ni siz ham xuddi shunday vositalarni o'zingiz yasashingiz mumkin. Aynan shuni keyingi bobda o'rganamiz.
14-bob mashqlari¶
Yechimlar berilmagan β har birini o'zingiz yozib,
tscbilan tekshiring. Mashqlar asta-sekin qiyinlashadi.
Kitobtipini yarating (id,nom,narx,sahifa). UndanPartial<Kitob>yordamidaKitobUpdatetipini hosil qiling va faqatnarxo'zgaradigan obyekt yozing.Sozlamatipida hamma maydon ixtiyoriy (?) bo'lsin.Required<Sozlama>bilan yangi tip yasab, unga to'liq to'ldirilgan obyekt bering. Bitta maydonni qoldirib ko'ring va xatoni o'qing.KonfigtipiniReadonly<...>qilib e'lon qiling, so'ng uning bir maydonini o'zgartirishga urinib ko'ring. Chiqqan xato xabarini izohlang.Foydalanuvchitipidan (id,ism,email,parol)Pickyordamida faqatidvaismbo'lganOmmaviyProfiltipini yasang.- Xuddi shu
FoydalanuvchitipidanOmityordamidaparolsiz tip yasang. Natija 4-mashqdagidan nimasi bilan farq qiladi? Pickga mavjud bo'lmagan maydon nomi (masalan"telefon") bering va TypeScript qanday ogohlantirishini ko'ring.Kun = "dushanba" | "seshanba" | "chorshanba"union'i uchunRecord<Kun, string>lug'atini yasang: har bir kunga qisqartma (masalan"Du") bering.- 7-mashqdagi lug'atdan bitta kunni qoldirib ketib, chiqqan "missing property" xatosini o'qing.
Record<string, number>tipida "mahsulot kodi -> miqdor" ochiq lug'atini yarating va unga uchta yozuv qo'shing.Holat = "yangi" | "ochiq" | "yopiq" | "arxiv"danExcludebilanarxivni olib tashlab,FaolHolattipini yasang.- Xuddi shu
HolatdanExtractbilan faqat"ochiq" | "yopiq"ni ajratib oling. NatijaExcludebilan olinganidan farq qiladimi? string | number | null | undefinedtipidanNonNullablebilannullvaundefinedni olib tashlang. Natija qanday tip bo'ladi?salomlash(ism: string): stringfunksiyasini yozing vaReturnType<typeof salomlash>bilan uning natija tipini oling.koordinata(x: number, y: number)funksiyasidanParameters<typeof koordinata>bilan argument tiplarini tuple sifatida oling va shu tipdagi massiv yarating.Promise<string[]>qaytaradiganasyncfunksiya yozing.Awaited<ReturnType<typeof funksiya>>bilanawaitdan keyingi tipni oling.Mahsulottipidan (id,nom,narx,tavsif?)Omit<..., "id">va undan keyinPartial<...>ni ketma-ket qo'llab, "id'siz va hammasi ixtiyoriy"MahsulotUpdatetipini yasang.PickvaRequiredni zanjirlab:Foydalanuvchidan faqatemailvatelefon?ni oling, so'ng ikkalasini ham majburiy qiling.Record<"kichik" | "orta" | "katta", number>bilan "o'lcham -> piksel" lug'atini yasang vasatisfiesorqali ham yozib ko'ring. Farqni tushuntiring.- Real forma misoli:
RoyxatdanOtishtipini yarating (ism,email,parol,parolTasdiq,roziman: boolean). Undan submit uchunOmit<..., "parolTasdiq">tipini, qoralama (draft) uchunPartial<...>tipini yasang. - Bitta tipdan kamida uchta utility (
Pick,Omit,Partial,Record,ReturnType...) yordamida turli ishchi tiplar yasang va har birining qachon kerakligini bir qatorda izohlab yozing (bitta "manba" tipdan butun ishchi tip oilasini qurish mashqi).