Mundarija (34)
- Bu darsda
- 1. Nega bu kerak?
- 2. const tur parametri
- 2.1 Yozuv
- 2.2 Uchta variant yonma-yon
- 2.3 Obyektlarda ham ishlaydi
- 3. NoInfer<T>: "bu yerdan chiqarma"
- 3.1 Muammo: noto'g'ri argument T ni kengaytiradi
- 3.2 Yechim: NoInfer
- 3.3 Qayerda ishlatiladi?
- 4. Tur argumentlarini boshqarish
- 4.1 Hammasi yoki hech biri
- 4.2 Qachon tur argumentini yozish kerak?
- 5. Keraksiz generic
- 5.1 Oltin qoida: tur parametri ikki marta uchrasin
- 5.2 Tur parametrini "pastga" tushiring
- 5.3 Ortiqcha tur parametri
- 5.4 Yaxshi generic: tekshiruv ro'yxati
- 5.5 O'qiluvchanlik ham o'lchov
- 6. Turlarni test qilish: @ts-expect-error
- 7. TypeScript ushlamaydigan tuzoq: Node tur xatosini bilmaydi
- 8. Ko'p uchraydigan xatolar
- 8.1 Chaqiruvchidan as const kutish
- 8.2 Standart qiymat T ni kengaytiradi
- 8.3 Tur argumentlarini qisman berish
- 8.4 Bitta joydagi tur parametri
- 8.5 Node "o'tdi" — demak tur to'g'ri deb o'ylash
- 9. Mashqlar
- 1-mashq (oson): Natija turlari
- 2-mashq (o'rta): Keraksiz generic'ni toping
- 3-mashq (qiyin): Amaliy tajriba — variantlar ro'yxati
- 10. Real ishda
- Xulosa
- Manbalar
TypeScript generics amaliyoti: const tur parametri, NoInfer va keraksiz generic
Qisqacha: Generic'lar ikki yo'nalishda xato qilishi mumkin: tur juda keng chiqariladi (
["osh"]→string[]) yoki noto'g'ri argumentdan chiqariladi.<const T>(TypeScript 5.0) chaqiruvchidanas consttalab qilmasdan literal turlarni saqlaydi.NoInfer<T>(TypeScript 5.4) esa "bu parametrdanTni chiqarma, faqat tekshir" deydi. Va eng muhim qoida: tur parametri kamida ikki joyni bog'lamasa — u keraksiz.
Bu darsda
consttur parametri bilan literal va tuple turlarni avtomatik saqlaysiz.NoInfer<T>bilan inference qaysi argumentdan bo'lishini boshqarasiz.- Tur argumentlarini qisman berib bo'lmasligini (
TS2558) bilasiz. - Keraksiz generic'ni taniysiz: "tur parametri ikki marta uchrasin" qoidasi.
@ts-expect-errorbilan turlarning o'zini test qilasiz.
Oldin bilishingiz kerak: Generic interface, type va klass, Generic cheklovlar va keyof, Massiv va tuple turlari (as const), Union va literal turlar.
1. Nega bu kerak?
O'tgan darslarda generic funksiyalar, turlar va klasslar yozdik. Bu dars — "ishlaydi" dan "yaxshi ishlaydi" ga o'tish. Ilg'or loyihalar va kutubxonalar kodida siz aynan shu darsdagi texnikalarni ko'rasiz.
Sardor porsiya o'lchamlari uchun yordamchi yozdi: ro'yxat beriladi, funksiya ro'yxatni va "bu qiymat ro'yxatdami?" tekshiruvini qaytaradi.
function defineOptions<T extends readonly string[]>(list: T) {
return { list };
}
const sizes = defineOptions(["kichik", "o'rta", "katta"]);
type Size = (typeof sizes.list)[number];
const wrong: Size = "XL";
console.log(wrong); // XLtsc — xatosiz. Lekin Size — string: "XL" ham o'tib ketdi. Sababi — inference massivni string[] deb kengaytirdi (Tur chiqarish darsidagi qoida). Tuzatish — chaqiruvda as const yozish: defineOptions(["kichik", …] as const). Lekin buni har chaqiruvchi eslashi kerak. Bitta joyda unutildi — himoya yo'q. Funksiya o'zi "menga aniq qiymatlar kerak" deya olishi kerak.
2. const tur parametri
2.1 Yozuv
TypeScript 5.0 (2023-yil mart) da tur parametri oldiga const qo'yish imkoni qo'shildi:
function defineOptions<const T extends readonly string[]>(list: T) {
return { list };
}
const sizes = defineOptions(["kichik", "o'rta", "katta"]);
type Size = (typeof sizes.list)[number];
const ok: Size = "o'rta";
console.log(ok); // o'rtaEndi sizes.list turi — readonly ["kichik", "o'rta", "katta"], Size esa — "kichik" | "o'rta" | "katta". Chaqiruvchi as const yozmadi, lekin natija xuddi yozgandek. <const T> — "bu parametrga berilgan literal qiymatni as const bilan berilgandek chiqar".
Endi "XL" ushlanadi:
function defineOptions<const T extends readonly string[]>(list: T) {
return { list };
}
const sizes = defineOptions(["kichik", "o'rta", "katta"]);
type Size = (typeof sizes.list)[number];
const wrong: Size = "XL";Kompilyator:
TS2322: Type '"XL"' is not assignable to type '"katta" | "kichik" | "o'rta"'.Tarjimasi: ""XL" turini "katta" | "kichik" | "o'rta" turiga berib bo'lmaydi". Ya'ni: "Size faqat shu uch o'lcham, XL ular orasida yo'q". Xabardagi union a'zolari alifbo tartibida — tsc 7 union'larni shunday chiqaradi. Siz yozgan tartib ham, bu tartib ham — bitta tur: union'da tartib ahamiyatsiz.
2.2 Uchta variant yonma-yon
| Funksiya | f(["osh", "manti"]) natijasi |
|---|---|
<T extends readonly string[]> |
string[] |
<const T extends readonly string[]> |
readonly ["osh", "manti"] |
<const T extends string[]> |
["osh", "manti"] |
Hover turlari tsc --declaration bilan tekshirilgan. Cheklovda readonly bo'lsa, natija ham readonly tuple bo'ladi — xuddi as const dagidek. Cheklov o'zgaruvchan massiv bo'lsa ham literallar saqlanadi, faqat readonly siz. Ko'pincha birinchisi kerak: ro'yxatni funksiya o'zgartirmaydi.
2.3 Obyektlarda ham ishlaydi
const tur parametri ichma-ich obyektlarni ham qotiradi:
function defineDish<const T>(dish: T): T {
return dish;
}
const osh = defineDish({ name: "Osh", sizes: ["S", "L"] });
console.log(osh.name, osh.sizes.length); // Osh 2Hover'da osh — { readonly name: "Osh"; readonly sizes: readonly ["S", "L"] }. Har qiymat literal, hammasi readonly.
const tur parametri va as const — qarindosh, lekin farqi bor. as const qiymat yoniga yoziladi va chaqiruvchining ishi. <const T> esa funksiya imzosida turadi va funksiya muallifining qarori. Kutubxona yozayotgan bo'lsangiz, ikkinchisi foydalanuvchini bir qadamdan ozod qiladi. Natija turi esa ikkala holatda ham bir xil.
Muhim chegara: const faqat chaqiruvda to'g'ridan-to'g'ri yozilgan literalga ta'sir qiladi. Oldin o'zgaruvchiga olingan massiv (const list = ["S", "L"]; defineDish(list)) allaqachon string[] — uni orqaga qaytarib bo'lmaydi.
Tekshirib ko'ring:
const names = ["Malika", "Bobur"]; const opts = defineOptions(names);—const Tbo'lsa hamopts.listturi qanday?
Javob
string[]. names e'lon qilingan paytda string[] deb chiqarilgan edi. const tur parametri faqat chaqiruvning o'zida yozilgan literalni ko'radi. Literallar kerak bo'lsa — ro'yxatni chaqiruvga to'g'ridan-to'g'ri yozing yoki names ni as const qiling.
3. NoInfer<T>: "bu yerdan chiqarma"
3.1 Muammo: noto'g'ri argument T ni kengaytiradi
Endi tanlov funksiyasi: ruxsat etilgan qiymatlar, foydalanuvchi kiritgani va standart qiymat. Kiritilgan qiymat ro'yxatda bo'lmasa — standart qaytsin:
function choose<T extends string>(
allowed: readonly T[],
value: string,
fallback: T,
): T {
return allowed.find((a) => a === value) ?? fallback;
}
const drink = choose(["choy", "kofe"], "kakao", "sharbat");
console.log(drink); // sharbattsc — xatosiz. Lekin "sharbat" ruxsat etilgan ro'yxatda yo'q-ku! Nima bo'ldi? TypeScript T ni hamma argumentlardan chiqardi: allowed dan "choy" | "kofe", fallback dan esa "sharbat". Natija: T = "choy" | "kofe" | "sharbat". Standart qiymat o'zi ruxsat ro'yxatini kengaytirib yubordi. Ikki holatni qadamma-qadam solishtiring:
| Qadam | fallback: T |
fallback: NoInfer<T> |
|---|---|---|
1. allowed dan nomzod |
"choy" | "kofe" |
"choy" | "kofe" |
2. fallback dan nomzod |
"sharbat" |
olinmaydi |
3. Yakuniy T |
"choy" | "kofe" | "sharbat" |
"choy" | "kofe" |
4. "sharbat" tekshiruvi |
o'tdi (u T ning o'zida) |
TS2345 |
Chap ustun — muammo, o'ng ustun — keyingi bo'limdagi yechim.
3.2 Yechim: NoInfer
TypeScript 5.4 (2024-yil mart) dagi NoInfer<T> — "bu o'rinda T ni chiqarishda qatnashma, faqat tekshir":
function choose<T extends string>(
allowed: readonly T[],
value: string,
fallback: NoInfer<T>,
): T {
return allowed.find((a) => a === value) ?? fallback;
}
const drink = choose(["choy", "kofe"], "kakao", "sharbat");Kompilyator:
TS2345: Argument of type '"sharbat"' is not assignable to parameter of type '"choy" | "kofe"'.Tarjimasi: ""sharbat" turidagi argumentni "choy" | "kofe" turidagi parametrga berib bo'lmaydi". Endi T faqat allowed dan chiqarildi: "choy" | "kofe". fallback esa shu tur bilan tekshirildi va "sharbat" rad etildi. Xabardagi union tartibi siz yozgandan farq qilishi mumkin — tsc 7 union a'zolarini o'z tartibida chiqaradi, ma'nosi bir xil.
NoInfer — tayyor tur (Array, Record kabi), import kerak emas. JavaScript'da u ham iz qoldirmaydi.
3.3 Qayerda ishlatiladi?
Qoida oddiy: asosiy manba bitta parametr, qolganlari esa unga mos kelishi kerak bo'lsa — qolganlarini NoInfer ga o'rang. Odatiy holatlar:
- standart qiymat (
fallback,defaultValue); - ro'yxatdan tanlangan boshlang'ich holat (
initial); - "faqat shu kalitlardan biri" degan qo'shimcha parametr.
Tekshirib ko'ring:
choose(["choy", "kofe"], "kakao", "kofe")—NoInferbilan xato bormi? Natija nima?
Javob
Xato yo'q: "kofe" ro'yxatda bor. "kakao" ro'yxatda yo'q, shuning uchun natija — standart qiymat "kofe". Ikkinchi parametr — string, uni tekshirish ishlash paytida, find bilan.
4. Tur argumentlarini boshqarish
4.1 Hammasi yoki hech biri
Tur argumentlarini o'zingiz yozsangiz — hammasini yozish kerak (standart qiymatli bo'lmasa):
function pair<A, B>(a: A, b: B): [A, B] {
return [a, b];
}
pair<string>("Osh", 35000);Kompilyator:
TS2558: Expected 2 type arguments, but got 1.Tarjimasi: "2 ta tur argumenti kutilgan edi, 1 ta berildi". TypeScript'da "birinchisini men aytaman, ikkinchisini o'zing chiqar" (qisman inference) yo'q. Yo hammasi chiqariladi, yo hammasi yoziladi. Chiqish yo'li — standart tur parametri (<A, B = unknown>) yoki funksiyani ikkiga bo'lish.
4.2 Qachon tur argumentini yozish kerak?
| Holat | Misol |
|---|---|
| Argumentlardan chiqarib bo'lmaydi | new Map<string, number>(), emptyList<Order>() |
| Chiqarilgan tur juda tor | useState<Order | null>(null) |
| Chiqarilgan tur juda keng | pair<string | number>(…) |
| Qolgan hollarda | yozmang — inference to'g'ri |
Ikkinchi qator React'dan (17-qism): null dan T = null chiqariladi, keyin buyurtmani yozib bo'lmaydi. Tur argumenti "aslida bu yerga Order ham keladi" deydi.
5. Keraksiz generic
5.1 Oltin qoida: tur parametri ikki marta uchrasin
TypeScript hujjatlaridagi generic yozish qoidalaridan eng muhimi: tur parametri kamida ikki joyda uchrashi kerak. Generic — bog'lanish. Bitta joydagi T hech narsani hech narsaga bog'lamaydi:
// ❌ T bitta joyda — generic hech narsa bermaydi
function greet<S extends string>(name: S): string {
return `Xush kelibsiz, ${name}!`;
}
// ✅ oddiy tur yetarli
function greetPlain(name: string): string {
return `Xush kelibsiz, ${name}!`;
}
console.log(greet("Malika") === greetPlain("Malika")); // trueIkkala funksiya bir xil qabul qiladi va bir xil qaytaradi. S faqat o'qishni qiyinlashtirdi. Natija turida S bo'lganda edi (masalan, `Xush kelibsiz, ${S}!` turi), u o'z o'rnida bo'lardi — bu Template literal types darsida.
5.2 Tur parametrini "pastga" tushiring
Ikki imzo — bir xil ish:
function first1<T>(items: readonly T[]): T | undefined {
return items[0];
}
function first2<A extends readonly unknown[]>(items: A): A[number] {
return items[0];
}
const a = first1([1, 2, 3]);
const b = first2([1, 2, 3]);
console.log(a, b); // 1 1Natija turlarini solishtiring: a — number | undefined, b — number. Ikkinchisi undefined ni yo'qotdi: A[number] — "massiv elementi", bo'sh massivda esa element yo'q. Bundan tashqari, first2 imzosini o'qish qiyin. Handbook qoidasi: tur parametrini eng kichik birlikka qo'ying — butun massivga emas, elementga (T[] dagi T).
5.3 Ortiqcha tur parametri
// ❌ F — keraksiz: u faqat bitta joyda
function keep<T, F extends (item: T) => boolean>(
items: T[],
test: F,
): T[];
// ✅
function keep<T>(items: T[], test: (item: T) => boolean): T[];F bitta joyda uchraydi — demak keraksiz. Kamroq tur parametri — sodda imzo, aniqroq xato xabarlari.
Bunday joylarni avtomatik topadigan qoida ham bor: typescript-eslint'dagi no-unnecessary-type-parameters ("keraksiz tur parametrlari yo'q"). U "faqat bir marta ishlatilgan" tur parametrlarini ko'rsatadi.
5.4 Yaxshi generic: tekshiruv ro'yxati
flowchart TD
A["Tur parametri<br/>kerakmi?"] --> B{"T 2 joyni<br/>bog'laydimi?"}
B -- "yo'q" --> C["Oddiy tur yoki unknown"]
B -- "ha" --> D{"T faqat natijadami?"}
D -- "ha" --> E["Yo'q: bu yashirin as<br/>(parse<T>)"]
D -- "yo'q" --> F["Generic — to'g'ri tanlov"]
F --> G["T ni eng kichik<br/>birlikka qo'ying"]Bu sxema Generics darsidagi "yolg'onchi generic" (parse<T>) qoidasini ham o'z ichiga oladi: natijadagi T hech qaysi parametrda bo'lmasa, u tekshiruv emas, va'da.
5.5 O'qiluvchanlik ham o'lchov
Generic imzo — funksiyaning hujjati. Uni boshqa dasturchi hover'da o'qiydi, xato xabarida ko'radi. Ikki imzoni solishtiring:
function a<T>(
items: readonly T[],
key: (item: T) => string,
): Map<string, T[]>;
function b<T, K extends string, F extends (x: T) => K>(
items: readonly T[],
key: F,
): Map<K, T[]>;Ikkinchisi "aqlliroq": kalitlarni literal turda saqlaydi. Lekin hover'da u ancha uzun, xato bo'lsa — xabar ham uch barobar uzun bo'ladi. Murakkab tur faqat foydasi aniq bo'lganda o'zini oqlaydi. Amaliy qoida: avval eng sodda imzoni yozing; chaqiruvchida haqiqiy muammo chiqqandagina (masalan, kalit turi kerak bo'lsa) murakkablashtiring.
Tekshirib ko'ring:
function toArray<T>(value: T): T[]— tur parametri nechta joyda uchraydi va u kerakmi?
Javob
Ikki joyda: parametrda (value: T) va natijada (T[]). U kirish va chiqishni bog'laydi: toArray(35000) — number[], toArray("Osh") — string[]. Demak generic to'g'ri. unknown bilan yozilganda natija unknown[] bo'lib, tur yo'qolardi.
6. Turlarni test qilish: @ts-expect-error
Generic'lar yozganda "bu chaqiruv xato berishi kerak" degan talab ham test qilinishi kerak. Masalan, choose ga ro'yxatda yo'q standart qiymat berilsa, tsc to'xtatishi kerak. Buning uchun maxsus izoh bor:
function choose<T extends string>(
allowed: readonly T[],
value: string,
fallback: NoInfer<T>,
): T {
return allowed.find((a) => a === value) ?? fallback;
}
// @ts-expect-error — "sharbat" ro'yxatda yo'q
choose(["choy", "kofe"], "kakao", "sharbat");
console.log(choose(["choy", "kofe"], "kakao", "choy")); // choy// @ts-expect-error — "keyingi qatorda tur xatosi bo'lishi kerak". Xato bo'lsa — tsc jim (blok tekshiruvdan o'tdi). Xato bo'lmasa — tsc o'zi xato beradi: TS2578: Unused '@ts-expect-error' directive. Ya'ni bu — tur darajasidagi test: kimdir NoInfer ni olib tashlasa, tsc darhol aytadi. Buni 3-mashqda ishlatasiz.
Uning qardoshi @ts-ignore esa xato bormi-yo'qmi — jim turadi. Shuning uchun u xavfli va kam ishlatiladi (TypeScript best practices darsida).
@ts-expect-error dan keyin izoh yozish odat: nega xato kutilmoqda (— "sharbat" ro'yxatda yo'q). Uch oydan keyin bu qatorni o'qigan dasturchi uni "eski, keraksiz" deb o'chirib yubormasligi uchun.
Tekshirib ko'ring: Kimdir
choosedanNoInferni olib tashladi. Testdagi@ts-expect-errorqatorida nima bo'ladi?
Javob
tsc TS2578: Unused '@ts-expect-error' directive. beradi. NoInfer siz "sharbat" T ni kengaytiradi va xato yo'qoladi — "kutilgan xato" chiqmagani esa o'zi xato. Tur testi o'zgarishni darhol ushladi.
7. TypeScript ushlamaydigan tuzoq: Node tur xatosini bilmaydi
Yuqoridagi blokda @ts-expect-error qatori bajarildi — choose chaqirildi va "sharbat" qaytdi. Node turlarni tekshirmaydi, faqat o'chiradi (TypeScript'ni o'rnatish darsi). Xuddi shu holat @ts-expect-error siz ham bo'ladi:
function choose<T extends string>(
allowed: readonly T[],
value: string,
fallback: NoInfer<T>,
): T {
return allowed.find((a) => a === value) ?? fallback;
}
const drink = choose(["choy", "kofe"], "kakao", "sharbat");
console.log(drink);Kompilyator:
TS2345: Argument of type '"sharbat"' is not assignable to parameter of type '"choy" | "kofe"'.Lekin node drink.ts bu faylni jim bajaradi:
sharbatMashqlardagi testlar ham shunday: node --test tur xatoli faylni ham ishga tushiradi va testlar "o'tishi" mumkin. Qoida: testdan oldin har doim npx tsc --noEmit (yoki npm run tip). vazifalar da npm test va npm run tip aynan shuning uchun alohida qadamlar, CI'da esa ikkalasi ham ishlaydi.
8. Ko'p uchraydigan xatolar
8.1 Chaqiruvchidan as const kutish
Funksiya literal turga tayanadi, lekin chaqiruvchi as const ni unutadi — tur string[] ga kengayadi. Tuzatish: <const T extends readonly …>.
8.2 Standart qiymat T ni kengaytiradi
fallback: T — noto'g'ri standart qiymat ruxsat ro'yxatiga qo'shilib ketadi. Tuzatish: fallback: NoInfer<T>.
8.3 Tur argumentlarini qisman berish
pair<string>(…) — TS2558. Tuzatish: hammasini yozing yoki standart tur parametri qo'shing.
8.4 Bitta joydagi tur parametri
greet<S extends string>(name: S): string — keraksiz. Tuzatish: name: string.
8.5 Node "o'tdi" — demak tur to'g'ri deb o'ylash
Node turlarni tekshirmaydi. Tuzatish: tsc --noEmit testdan oldin.
9. Mashqlar
1-mashq (oson): Natija turlari
function plain<T extends readonly string[]>(items: T): T {
return items;
}
function frozen<const T extends readonly string[]>(items: T): T {
return items;
}
const a = plain(["S", "M"]);
const b = frozen(["S", "M"]);
console.log(a.length, b.length); // 2 2a ning turi: [:string[]]. b[0] ning turi (literal): [:"S"]. b.length ning turi (literal son): .
Yechim
a—string[]: oddiy inference massivni kengaytiradi.b—readonly ["S", "M"],b[0]—"S":consttur parametri literallarni saqladi.b.length—2: tuple uzunligi literal tur (Massiv va tuple turlari).
2-mashq (o'rta): Keraksiz generic'ni toping
Quyidagi uch funksiyadan qaysi birida tur parametri keraksiz? Uni oddiy turga almashtiring.
function wrap<T>(value: T): { value: T } { … }
function total<P extends number>(prices: P[]): number { … }
function lastOf<T>(items: readonly T[]): T | undefined { … }Yechim
total da: P faqat parametrda, natija esa oddiy number. Yig'indi P ga bog'liq emas.
function total(prices: readonly number[]): number {
return prices.reduce((sum, p) => sum + p, 0);
}
console.log(total([35000, 5000])); // 40000wrap va lastOf da T ikki joyda — parametr va natijani bog'laydi. Ular to'g'ri generic.
3-mashq (qiyin): Amaliy tajriba — variantlar ro'yxati
Mashq kurs/mashqlar/15/ papkasida. 23-ilgor/options.ts:
defineOptions(list)—{ list, has(value) }qaytarsin;has— tur predikati (value is …): satr ro'yxatdagi qiymatlardan birimi?choose(allowed, value, fallback)—valuero'yxatda bo'lsa o'zi, bo'lmasafallback.fallbackham ro'yxatdan bo'lishi shart.
Avval const va NoInfer siz yozing. Testda tur talablarini @ts-expect-error bilan tekshiring: const wrong: Size = "XL" va choose(SIZES.list, "XL", "ulkan") — ikkalasi ham tur xatosi bo'lishi kerak. npx tsc --pretty false nima deydi? Keyin const va NoInfer qo'shing.
Yechim
Birinchi variantda tsc 7.0.2:
23-ilgor/options.test.ts(13,3): error TS2578: Unused '@ts-expect-error' directive.
23-ilgor/options.test.ts(24,3): error TS2578: Unused '@ts-expect-error' directive."Ishlatilmagan @ts-expect-error" — ya'ni kutilgan xatolar chiqmadi: Size — string, "ulkan" esa T ni kengaytirdi. Tur testlari ikkala zaiflikni ham ushladi.
// 23-ilgor/options.ts — variantlar ro'yxati va xavfsiz tanlov
export function defineOptions<const T extends readonly string[]>(
list: T,
) {
return {
list,
// Tur predikati: satr ro'yxatdagi qiymatlardan birimi?
has(value: string): value is T[number] {
return list.includes(value);
},
};
}
// value ro'yxatda bo'lsa — o'zi, bo'lmasa — fallback.
// NoInfer: fallback T ni kengaytirmaydi, ro'yxatdan bo'lishi shart
export function choose<T extends string>(
allowed: readonly T[],
value: string,
fallback: NoInfer<T>,
): T {
return allowed.find((a) => a === value) ?? fallback;
}// 23-ilgor/options.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { defineOptions, choose } from "./options.ts";
const SIZES = defineOptions(["kichik", "o'rta", "katta"]);
type Size = (typeof SIZES.list)[number];
test("defineOptions: ro'yxat va tekshiruv", () => {
const size: Size = "o'rta";
assert.equal(SIZES.has(size), true);
assert.equal(SIZES.has("XL"), false);
// @ts-expect-error — "XL" o'lchamlar ro'yxatida yo'q
const wrong: Size = "XL";
assert.equal(SIZES.has(wrong), false);
});
test("choose: ruxsat etilgan yoki standart", () => {
assert.equal(choose(SIZES.list, "katta", "o'rta"), "katta");
assert.equal(choose(SIZES.list, "XL", "o'rta"), "o'rta");
});
test("choose: standart qiymat ham ro'yxatdan bo'lsin", () => {
// @ts-expect-error — "ulkan" ro'yxatda yo'q
const size = choose(SIZES.list, "XL", "ulkan");
assert.equal(size, "ulkan");
});value is T[number]—T[number]— tuple elementlari union'i (keyof,typeofva indexed access darsida).has("o'rta")dan keyin TypeScript satrniSizedeb biladi.- Uchinchi testdagi
assert.equal(size, "ulkan")ataylab: «Node tur xatosini bilmaydi» bo'limidagi holat. Tur xatosi bor qator ham bajariladi —@ts-expect-erroruni faqattscuchun "kutilgan" deb belgilaydi.
npx tsc --pretty false — chiqishsiz. node --test 23-ilgor/options.test.ts bizda (Node 24.21.0) shunday chiqdi:
✔ defineOptions: ro'yxat va tekshiruv (0.9726ms)
✔ choose: ruxsat etilgan yoki standart (0.1954ms)
✔ choose: standart qiymat ham ro'yxatdan bo'lsin (0.1742ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 158.3124E'tibor bering: birinchi (zaif) variantda ham node --test uchala testdan o'tardi — tur zaifligini faqat tsc ko'rdi. XATOLAR.md ga qo'shing: TS2558, TS2578, NoInfer dagi TS2345. Keyin kurs/mashqlar papkasidan:
git add 15/23-ilgor 15/XATOLAR.md
git commit -m "15/23: options.ts — const tur parametri va NoInfer"10. Real ishda
- Kutubxona API'lari: marshrutlar, holat mashinalari, forma sxemalari kabi kutubxonalar
consttur parametri bilan foydalanuvchi yozgan nomlarni ("/menu","tayyor") aniq turga aylantiradi. Ilgari ular hujjatda "as constyozing" deb so'rardi. NoInfer— "standart qiymat", "boshlang'ich holat" parametrlarida: kutubxona mualliflari uchun kichik, lekin qimmatli vosita.- Tur testlari: kutubxonalarda
@ts-expect-errorbilan to'la*.test-d.tsfayllar bor — ular API turlarining o'zini himoya qiladi. - Kod ko'rib chiqishda "bu tur parametri bir marta ishlatilgan" — tez-tez yoziladigan izoh.
- Intervyu: "
consttur parametrias constdan nimasi bilan farq qiladi?", "NoInfernimaga kerak?", "Generic qachon keraksiz?" — middle/senior savollari.
Xulosa
<const T>— chaqiruvdagi literalnias constbilan berilgandek chiqaradi;readonlycheklov bilan —readonlytuple. Faqat to'g'ridan-to'g'ri yozilgan literalga ta'sir qiladi.NoInfer<T>— shu parametrTni chiqarishda qatnashmaydi, faqat tekshiriladi. Standart qiymatlar uchun.- Tur argumentlari — hammasi yoki hech biri (
TS2558); qisman inference yo'q. - Tur parametri kamida ikki joyni bog'lasin, eng kichik birlikka qo'yilsin; natijadagina bo'lsa — bu yashirin
as. @ts-expect-error— tur testi. Node turlarni tekshirmaydi: testdan oldintsc --noEmit.
Keyingi dars: Function overload va this turi — bitta funksiya turli kirishga turli natija turi qaytarishi kerak bo'lsa.
Manbalar
- TypeScript 5.0 Release Notes: "
constType Parameters" — typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html - TypeScript 5.4 Release Notes: "Preserved Narrowing… / The
NoInferUtility Type" — typescriptlang.org/docs/handbook/release-notes/typescript-5-4.html - TypeScript Handbook: "More on Functions" (Guidelines for Writing Good Generic Functions) — typescriptlang.org/docs/handbook/2/functions.html
- typescript-eslint:
no-unnecessary-type-parameters— typescript-eslint.io/rules/no-unnecessary-type-parameters
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!