16-bo‘lim
Tashqi kutubxonalar va @types
Turlar qayerdan keladi, .d.ts yozish, modul va global kengaytirish, ikki bosqichli tasdiqlash.
Ushbu bo‘lim mundarijasi
Haqiqiy loyihada kodning katta qismi sizniki emas -
node_modules ichida yotadi. TypeScript ular haqida qayerdan
biladi?
Uch yo'l bor, va har biri uchun o'z hal qilish usuli.
Turlari o'zi bilan keladigan paket #
import { readFileSync } from "node:fs";
const matn: string = readFileSync("/etc/hostname", "utf8");
console.log(matn.trim().length > 0);
tsx src/fs.ts
true
Noto'g'ri ishlatilsa darhol tutiladi:
import { readFileSync } from "node:fs";
const matn: number = readFileSync("/etc/hostname", "utf8");
tsc --noEmit 2>&1 | fold -sw 74
src/fs2.ts(3,7): error TS2322: Type 'string' is not assignable to type
'number'.
Bu bilim @types/node paketidan keladi:
ls /ish/node_modules/@types/
echo "--- @types/node hajmi ---"
du -sh /ish/node_modules/@types/node | cut -f1
echo "--- fs e'loni ---"
head -4 /ish/node_modules/@types/node/fs.d.ts
node
--- @types/node hajmi ---
2.4M
--- fs e'loni ---
/**
* The `node:fs` module enables interacting with the file system in a
* way modeled on standard POSIX functions.
*
2.4 megabayt - faqat turlar uchun. Ular kompilyatsiyadan keyin hech qanday kod qoldirmaydi.
| Manba | Misol | Qanday topiladi |
|---|---|---|
| Paketning o'zida | zod, tsx | package.json dagi types |
@types/* | @types/node | Avtomatik, node_modules/@types |
| Sizning faylingiz | src/*.d.ts | include ichida bo'lsa |
Birinchisi eng yaxshi: kutubxona va uning turlari birga
yangilanadi. @types/* esa alohida jamoa tomonidan
yuritiladi (DefinitelyTyped loyihasi), shuning uchun ba'zan
kutubxona versiyasidan orqada qoladi.
Turlanmagan modul #
export function salom(ism) {
return "Salom, " + ism + "!";
}
import { salom } from "./eski";
console.log(salom("Husanboy"));
tsc --noEmit 2>&1 | fold -sw 74
src/asosiy.ts(1,23): error TS7016: Could not find a declaration file for
module './eski'. '/ish/dars/src/eski.js' implicitly has an 'any' type.
TS7016 - "turlarni topa olmadim". Bu xato noImplicitAny
tufayli chiqadi.
Eng oson yo'l - allowJs:
export function salom(ism) {
return "Salom, " + ism + "!";
}
import { salom } from "./eski";
console.log(salom("Husanboy"));
console.log(salom(42));
tsc --noEmit --allowJs && echo "tsc: xato yo_q"
tsx src/asosiy.ts
tsc: xato yo_q
Salom, Husanboy!
Salom, 42!
Ishladi - lekin salom(42) ham o'tdi. allowJs faylni
qo'shadi, tekshiruvni esa kuchaytirmaydi.
.d.ts fayl yozish #
export function salom(ism) {
return "Salom, " + ism + "!";
}
export declare function salom(ism: string): string;
import { salom } from "./eski";
console.log(salom("Husanboy"));
console.log(salom(42));
tsc --noEmit 2>&1 | fold -sw 74
src/asosiy.ts(3,19): error TS2345: Argument of type 'number' is not
assignable to parameter of type 'string'.
.d.ts - faqat e'lonlar fayli. Unda hech qanday
bajariladigan kod yo'q, faqat "bu modulda nima bor" degan
tavsif.
declare kalit so'zi "amalga oshirish boshqa joyda" degani.
Tashqi paket uchun e'lon #
Paketning o'zida ham, @types da ham turlar bo'lmasa, o'zingiz
e'lon qilasiz:
declare module "sodda-dokon" {
export function narxla(nomi: string): number;
export const QQS: number;
}
import { narxla, QQS } from "sodda-dokon";
const n: number = narxla("Olma");
console.log(n + QQS);
tsc --noEmit && echo "tsc: xato yo_q"
echo "--- ishga tushirsak ---"
tsx src/asosiy.ts 2>&1 | grep -o "ERR_MODULE_NOT_FOUND" | head -1
tsc: xato yo_q
--- ishga tushirsak ---
ERR_MODULE_NOT_FOUND
Bu - juda muhim natija. sodda-dokon degan paket umuman
mavjud emas, lekin tsc hech narsa demadi.
declare module - 7-bobdagi tur predikati kabi va'da.
Kompilyator uni tekshirmaydi.
Shu bilan birga, e'lon ichidagi qoidalar ishlaydi:
declare module "sodda-dokon" {
export function narxla(nomi: string): number;
}
import { narxla } from "sodda-dokon";
const n: string = narxla(12000);
tsc --noEmit 2>&1 | fold -sw 74
src/asosiy.ts(2,7): error TS2322: Type 'number' is not assignable to type
'string'.
src/asosiy.ts(2,26): error TS2345: Argument of type 'number' is not
assignable to parameter of type 'string'.
Modul kengaytirish #
8-bobdagi e'lon birlashuvi bu yerda ish beradi - declare
module ni bir necha marta yozish mumkin:
declare module "sodda-dokon" {
export function narxla(nomi: string): number;
}
declare module "sodda-dokon" {
export function chegirma(narx: number, foiz: number): number;
}
import { narxla, chegirma } from "sodda-dokon";
const a: number = narxla("Olma");
const b: number = chegirma(a, 20);
console.log(a, b);
tsc --noEmit && echo "tsc: ikkala elon ham korindi"
tsc: ikkala elon ham korindi
Amalda bu mavjud kutubxonaga qo'shimcha qilish uchun
ishlatiladi - masalan Express ning Request obyektiga
foydalanuvchi maydonini qo'shish.
Global kengaytirish #
Eng ko'p uchraydigan holat - muhit o'zgaruvchilari:
console.log(process.env.DOKON_NOMI.length);
tsc --noEmit 2>&1 | fold -sw 74
src/env.ts(1,13): error TS18048: 'process.env.DOKON_NOMI' is possibly
'undefined'.
Standart holatda process.env ning har bir maydoni string |
undefined - to'g'ri, chunki o'zgaruvchi berilmagan bo'lishi
mumkin.
Ma'lum o'zgaruvchilarni e'lon qilsak:
declare global {
namespace NodeJS {
interface ProcessEnv {
DOKON_NOMI: string;
}
}
}
export {};
process.env.DOKON_NOMI = "Husanboy dokoni";
console.log(process.env.DOKON_NOMI.length);
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/env.ts
tsc: xato yo_q
15
globalThis ga ham qo'shish mumkin:
declare global {
var dokonNomi: string;
}
globalThis.dokonNomi = "Dokon";
console.log(globalThis.dokonNomi, dokonNomi);
export {};
tsx src/glob.ts
Dokon Dokon
ProcessEnv ga DOKON_NOMI: string deb yozganingizda siz
kompilyatorga "bu o'zgaruvchi doim bor" deb aytasiz.
Agar .env faylida u bo'lmasa, dastur ish vaqtida
undefined oladi va yiqiladi - tsc esa hech narsa
demaydi.
Xavfsizroq yo'l: e'lonni string | undefined qoldirib,
dastur boshida bir marta tekshiring:
const DOKON_NOMI = process.env.DOKON_NOMI;
if (!DOKON_NOMI) throw new Error("DOKON_NOMI berilmagan");
Endi qolgan kod string bilan ishlaydi va va'da haqiqiy
tekshiruvga tayanadi.
Ikki bosqichli tasdiqlash #
Kutubxonaning turlari noto'g'ri bo'lsa, as bilan tuzatmoqchi
bo'lasiz. TypeScript esa ruxsat bermaydi:
type Mahsulot = { nomi: string; narx: number };
const xom: string = "Olma";
const a = xom as Mahsulot;
tsc --noEmit 2>&1 | fold -sw 74
src/ikki.ts(5,11): error TS2352: Conversion of type 'string' to type
'Mahsulot' may be a mistake because neither type sufficiently overlaps
with the other. If this was intentional, convert the expression to
'unknown' first.
Xabar yo'lni o'zi ko'rsatdi:
type Mahsulot = { nomi: string; narx: number };
const xom: string = "Olma";
const a = xom as unknown as Mahsulot;
console.log(a.nomi);
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/ikki2.ts
tsc: xato yo_q
undefined
as unknown as T har qanday turni har qanday turga
aylantiradi. Natija - undefined, chunki satrda nomi
maydoni yo'q.
as unknown as - eng kuchli va eng xavfli yozuv| Yozuv | Kuchi |
|---|---|
as T | Faqat yaqin turlar orasida |
as unknown as T | Har qanday turdan har qandayiga |
@ts-expect-error | Bitta qatordagi xatoni o'chiradi |
Kodda as unknown as ni ko'rsangiz, yoniga izoh yozilgan
bo'lishi kerak: nega bu kerak va qachon olib tashlanadi.
@ts-ignore o'rniga @ts-expect-error ishlating: xato
tuzalgach, u o'zi "endi xato yo'q" deb ogohlantiradi.
Xulosa #
- Turlar uch manbadan keladi: paketning o'zidan,
@types/*dan yoki sizning.d.tsfaylingizdan. - Paket bilan birga keladigan turlar eng ishonchli - ular kutubxona bilan birga yangilanadi.
@types/*ni DefinitelyTyped jamoasi yuritadi va u versiyadan orqada qolishi mumkin.- Turlanmagan modul
TS7016beradi;allowJsfaylni qo'shadi, lekin tekshiruvni kuchaytirmaydi. .d.ts- faqat e'lonlar fayli;declare"amalga oshirish boshqa joyda" degani.declare module "nomi"mavjud bo'lmagan paket uchun ham yoziladi -tscuni tekshirmaydi.- E'lon ichidagi imzolar esa to'liq kuchda ishlaydi.
declare moduleni bir necha marta yozib, mavjud kutubxonani kengaytirish mumkin.declare globalbilanprocess.envvaglobalThisni turlash mumkin - lekin bu ham tekshirilmaydigan va'da.- Muhit o'zgaruvchilarini dastur boshida bir marta tekshirib,
keyin oddiy
stringsifatida uzating. as unknown as Thar qanday turni aylantiradi; uni faqat izoh bilan birga ishlating.@ts-ignoreemas,@ts-expect-erroryozing.
node:fsdan funksiya import qilib, natijasini noto'g'ri turga berib ko'ring.node_modules/@typesichida nima borligini ko'ring.- Turlanmagan
.jsfayl yaratib,TS7016ni chaqiring. --allowJsbilan uni qo'shing va tekshiruv yo'qligini tasdiqlang.- Unga
.d.tsyozib, noto'g'ri argumentni tutiladigan qiling. - Mavjud bo'lmagan paket uchun
declare moduleyozing vatscjim turishini ko'ring. - Uni ishga tushirib,
ERR_MODULE_NOT_FOUNDni oling. declare globalbilanprocess.envga o'z o'zgaruvchingizni qo'shing.- Xavfsizroq variantni - dastur boshida tekshirishni - yozing.
as unknown asbilan satrni obyektga aylantiring va natijasi negaundefinedekanini tushuntiring.
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.