15-bo‘lim
any, unknown va never
Uchta maxsus tur, JSON.parse xavfi, bo'sh obyekt turining kutilmagan kengligi va ularni to'g'ri tanlash.
Ushbu bo‘lim mundarijasi
Tur tizimining chekkalarida uchta maxsus tur turadi:
| Tur | Ma'nosi |
|---|---|
any | "Tekshirishni to'xtat" |
unknown | "Hali bilmayman" |
never | "Bunday qiymat bo'lmaydi" |
Ular oson chalkashtiriladi, holbuki farqi juda katta.
any zanjir bo'ylab tarqaladi #
const javob: any = { nomi: "Olma" };
const nomi = javob.nomi;
const uzunlik = nomi.length;
const yakun = uzunlik.toUpperCase();
console.log(yakun);
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/any.ts 2>&1 | grep -oE "TypeError.*" | head -1
tsc: xato yo_q
TypeError: uzunlik.toUpperCase is not a function
Uchta o'zgaruvchi, uchtasi ham any. Hech qaysisiga tur
yozilmagan, lekin hech qaysisi tekshirilmadi ham.
any bitta o'zgaruvchini emas, undan kelib chiqadigan
butun zanjirni himoyasiz qoldiradi.
Bitta istisno bor - arifmetika:
const xom: any = "12000";
const narx = xom * 2;
const yakun = narx.toUpperCase();
tsc --noEmit 2>&1 | fold -sw 74
src/any2.ts(4,20): error TS2339: Property 'toUpperCase' does not exist on
type 'number'.
any * 2 - number, chunki * boshqa natija berolmaydi.
Shu joyda zanjir uzildi va tekshiruv qaytadi.
unknown darhol to'xtatadi #
const xom: unknown = "12000";
console.log(xom.length);
tsc --noEmit 2>&1 | fold -sw 74
src/unknown.ts(2,13): error TS18046: 'xom' is of type 'unknown'.
unknown ham istalgan qiymatni qabul qiladi - lekin uni
ishlatishdan oldin tekshirish talab qilinadi:
function uzunlik(x: unknown): number {
if (typeof x === "string") return x.length;
if (Array.isArray(x)) return x.length;
return 0;
}
console.log(uzunlik("Olma"), uzunlik([1, 2, 3]), uzunlik(42));
tsx src/unknown2.ts
4 3 0
Tayinlash yo'nalishi #
let a: any = 1;
let u: unknown = 1;
let s: string;
s = a;
u = a;
a = u;
s = u;
tsc --noEmit 2>&1 | fold -sw 74
src/yonalish.ts(8,1): error TS2322: Type 'unknown' is not assignable to
type 'string'.
To'rtta tayinlashdan faqat bittasi xato berdi:
| Yo'nalish | Ruxsat |
|---|---|
any → istalgan tur | Ha |
any → unknown | Ha |
unknown → any | Ha |
unknown → aniq tur | Yo'q |
Aynan shu qator unknown ni any dan ajratib turadi.
JSON.parse - any ning eng keng tarqalgan manbai #
const javob = JSON.parse('{"nomi":"Olma"}');
console.log(javob.narx.toFixed(2));
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/json.ts 2>&1 | grep -oE "TypeError.*" | head -1
tsc: xato yo_q
TypeError: Cannot read properties of undefined (reading 'toFixed')
JSON.parse any qaytaradi - boshqa ilojisi yo'q, chunki
satrning ichida nima borligini kompilyator bilolmaydi.
Muammo shundaki, any jimgina keladi. Yechim - uni darhol
unknown ga aylantirib, tekshirish:
type Mahsulot = { nomi: string; narx: number };
function mahsulotmi(x: unknown): x is Mahsulot {
if (typeof x !== "object" || x === null) return false;
const o = x as Record<string, unknown>;
return typeof o.nomi === "string" && typeof o.narx === "number";
}
const a: unknown = JSON.parse('{"nomi":"Olma"}');
const b: unknown = JSON.parse('{"nomi":"Anor","narx":25000}');
console.log(mahsulotmi(a) ? a.narx : "notogri malumot");
console.log(mahsulotmi(b) ? b.narx : "notogri malumot");
tsx src/json2.ts
notogri malumot
25000
Birinchi javobda narx yo'q edi - va u ish vaqtida, to'g'ri
joyda tutildi.
Tashqi ma'lumot kiradigan har bir joyda - fetch,
JSON.parse, localStorage, forma, process.env - turni
unknown deb belgilang va bir marta tekshiring.
Katta loyihada buni qo'lda yozish zerikarli. Tayyor yechimlar:
| Kutubxona | Yondashuv |
|---|---|
| Zod | Sxema yozasiz, tur o'zi chiqadi |
| Valibot | Zod ga o'xshash, kichikroq |
| TypeBox | JSON Schema bilan mos |
Ular 7-bobdagi tur predikatini avtomatik yasaydi.
catch dagi e #
try {
throw new Error("xato yuz berdi");
} catch (e) {
console.log(e.message);
}
tsc --noEmit 2>&1 | fold -sw 74
src/catch.ts(4,15): error TS18046: 'e' is of type 'unknown'.
JavaScript da throw istalgan qiymatni tashlashi mumkin -
satr, son, obyekt. Shuning uchun e - unknown:
function xabar(e: unknown): string {
if (e instanceof Error) return e.message;
return String(e);
}
try {
throw new Error("xato yuz berdi");
} catch (e) {
console.log(typeof e, "|", xabar(e));
}
try {
throw "oddiy satr";
} catch (e) {
console.log(typeof e, "|", xabar(e));
}
tsx src/catch2.ts
object | xato yuz berdi
string | oddiy satr
Ikkinchi holat ko'rsatib turibdi: catch ga har doim Error
kelmaydi.
Bo'sh obyekt turi {} #
Bu - eng ko'p chalkashtiriladigan tur:
const a: {} = "Olma";
const b: {} = 12000;
const c: {} = true;
const d: {} = { nomi: "Olma" };
const e: {} = null;
tsc --noEmit 2>&1 | fold -sw 74
src/bosh.ts(5,7): error TS2322: Type 'null' is not assignable to type
'{}'.
Satr ham, son ham, mantiqiy qiymat ham o'tdi. {} "bo'sh
obyekt" degani emas - u "null va undefined dan
boshqa hamma narsa" degani.
Va undan hech qanday foyda yo'q:
const a: {} = "Olma";
console.log(a.length);
tsc --noEmit 2>&1 | fold -sw 74
src/bosh2.ts(2,15): error TS2339: Property 'length' does not exist on
type '{}'.
object esa haqiqatan obyektlarni talab qiladi:
const a: object = { nomi: "Olma" };
const b: object = [1, 2];
const c: object = () => 1;
const d: object = "Olma";
tsc --noEmit 2>&1 | fold -sw 74
src/obyekt.ts(4,7): error TS2322: Type 'string' is not assignable to type
'object'.
Massiv va funksiya ham obyekt - faqat satr o'tmadi.
| Tur | Nimani qabul qiladi |
|---|---|
{} | null va undefined dan boshqa hammasi |
object | Obyekt, massiv, funksiya |
Record<string, unknown> | Kalitli obyekt |
unknown | Hamma narsa |
Amalda: "istalgan qiymat" uchun unknown, "kalitli obyekt"
uchun Record<string, unknown> yozing. {} va Object ni
esa umuman ishlatmang.
never unionda yo'qoladi #
type A = string | never;
type B = string | unknown;
const a: A = "Olma";
const b: B = 12000;
console.log(a, b);
tsx src/union.ts
Olma 12000
B ga son berildi - demak string | unknown aslida unknown
ga teng. A ni tekshiramiz:
type A = string | never;
const c: A = 42;
tsc --noEmit 2>&1 | fold -sw 74
src/union2.ts(3,7): error TS2322: Type 'number' is not assignable to type
'string'.
Xato xabari A ni string deb atadi - never izsiz
yo'qolgan.
void, undefined va never #
function xatoBer(m: string): never {
throw new Error(m);
}
function hechnima(): void {}
function aniqmas(): undefined {
return undefined;
}
console.log(typeof hechnima(), aniqmas());
console.log(typeof xatoBer);
tsx src/void.ts
undefined undefined
function
Ish vaqtida uchalasi ham undefined bilan bog'liq, lekin
turlar darajasida farq bor:
const a: void = undefined;
const b: undefined = undefined;
const c: never = undefined;
tsc --noEmit 2>&1 | fold -sw 74
src/never.ts(3,7): error TS2322: Type 'undefined' is not assignable to
type 'never'.
| Tur | Ma'nosi |
|---|---|
void | Funksiya tugaydi, natijaga qiziqilmaydi |
undefined | Aniq undefined qiymati |
never | Funksiya tugamaydi yoki qiymat mavjud emas |
any[] va unknown[] #
const xom: any[] = [1, "ikki", true];
const birinchi = xom[0];
birinchi.qandaydirMetod();
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/massiv.ts 2>&1 | grep -oE "TypeError.*" | head -1
tsc: xato yo_q
TypeError: birinchi.qandaydirMetod is not a function
const xom: unknown[] = [1, "ikki", true];
const birinchi = xom[0];
birinchi.qandaydirMetod();
tsc --noEmit 2>&1 | fold -sw 74
src/massiv2.ts(4,1): error TS18046: 'birinchi' is of type 'unknown'.
Aralash massiv kerak bo'lsa, any[] emas, unknown[] yoki
aniq union - (string | number)[] - yozing.
any qayerdan kelib qoladiSiz yozmasangiz ham any paydo bo'ladi:
| Manba | Yechim |
|---|---|
JSON.parse | unknown ga o'tkazib tekshiring |
Turlanmagan npm paketi | @types/* yoki o'z e'loningiz (16-bob) |
catch (e) | strict da allaqachon unknown |
Eski .js fayllar | allowJs bilan asta ko'chiring (18-bob) |
as any | Deyarli har doim keraksiz |
tsc --noEmit --noImplicitAny bilan yashirin any larni
topasiz, lekin ochiq yozilganlarini topa olmaysiz. Buning
uchun ESLint ning no-explicit-any qoidasi kerak.
Xulosa #
anytekshiruvni o'chiradi va butun zanjir bo'ylab tarqaladi; faqat arifmetika uni to'xtatadi.unknownham hamma qiymatni qabul qiladi, lekin uni ishlatishdan oldin tekshirish majburiy.unknownni aniq turga berib bo'lmaydi - bu ikkalasining asosiy farqi.JSON.parseanyqaytaradi; natijaniunknowndeb belgilab, tur predikati bilan tekshiring.- Tashqi ma'lumot kiradigan har bir chegarada tekshiring; katta loyihada Zod kabi kutubxona qulay.
catch (e)dae-unknown, chunki JavaScript istalgan qiymatni tashlashi mumkin.{}"bo'sh obyekt" emas - unullvaundefineddan boshqa hamma narsani qabul qiladi va hech narsa bermaydi.objectobyekt, massiv va funksiyani qabul qiladi, primitivlarni esa yo'q.- Unionda
neveryo'qoladi,unknownesa qolgan hammasini yutadi. void,undefinedvaneveruchtasi uch xil narsa.- Aralash massiv uchun
any[]emas,unknown[]yoki aniq union yozing.
anydan boshlanadigan uch bosqichli zanjir yozing va dasturni yiqiting.anyni arifmetikada ishlatib, tekshiruv qaytganini ko'ring.unknownni to'g'ridan-to'g'ri ishlatib,TS18046ni oling.typeofvaArray.isArraybilan uni toraytiring.unknownnistringga berib,TS2322ni chaqiring.JSON.parsenatijasini tekshirmasdan ishlatib, dasturni yiqiting.- Tur predikati yozib, o'sha kodni xavfsiz qiling.
catch (e)dae.messageyozib,TS18046ni oling, keyininstanceofbilan tuzating.{}turiga satr, son vanullberib, qaysi biri o'tishini aniqlang.any[]vaunknown[]ni solishtirib, farqni bir jumlada yozing.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.