Tarkibga o'tish

21 β€” Tashqi kutubxonalar va @types

⬅️ Oldingi: 20 β€” Async, Promise va tiplangan API Β· 🏠 README Β· Keyingi: 22 β€” React va Node bilan TypeScript ➑️

Bu bobda: real loyiha hech qachon faqat o'z kodingizdan iborat bo'lmaydi β€” npm install bilan o'nlab tashqi kutubxona qo'shasiz. Lekin ularning hammasi ham TypeScript'ni "bilmaydi". Shu bobda kutubxona tiplari qayerdan kelishini (kutubxona ichidagi built-in .d.ts, alohida @types/... paketi yoki o'zingiz yozadigan deklaratsiya), TypeScript tipni qanday tartibda qidirishini, tipsiz kutubxonaga declare module bilan tez tip berishni, skipLibCheckning nima qilishini, kutubxona tiplarini o'qib chiqishni, versiya mosligini va o'z paketingizga types maydoni qo'shishni ko'rib chiqamiz.


Muammo

20-bobgacha biz yozgan kodning hammasi o'zimizniki edi: o'zimiz tiplagan funksiya, interface, generic. Lekin haqiqiy loyihada birinchi kuniyoq begona kod qo'shasiz:

npm install lodash

lodash β€” millionlab loyiha ishlatadigan mashhur JavaScript yordamchi kutubxonasi. Import qilib ishlatamiz:

import _ from "lodash";

const bo_laklar = _.chunk([1, 2, 3, 4, 5], 2);

Va TypeScript darrov qizil chiziq chizadi:

error TS7016: Could not find a declaration file for module 'lodash'.
  '.../node_modules/lodash/lodash.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/lodash` if it exists or add a new
  declaration (.d.ts) file containing `declare module 'lodash';`

Birinchi qarashda g'alati: kutubxona o'rnatildi, import to'g'ri, lekin TypeScript "tip topa olmadim" deydi. Sabab oddiy: lodash β€” bu JavaScript kutubxonasi. Uning ichida .js fayllari bor, lekin TypeScript tiplari (.d.ts) yo'q. TypeScript esa har bir import qilingan modulning tipini bilishni xohlaydi β€” yo'q bo'lsa, "bu narsa any" deydi, strict rejimda esa buni xato sifatida ko'rsatadi.

Bu bobning butun mavzusi shu bitta savol atrofida: tashqi kutubxonaning tiplari qayerdan keladi va men nima qilishim kerak? Javob uchta ehtimoldan iborat, va ularni eng yaxshisidan eng oxirgi chorasigacha tartib bilan ko'ramiz.

Kutubxona tiplari uchta manbadan keladi: built-in d.ts, alohida @types paketi yoki o'zingiz yozgan deklaratsiya

.d.ts nima β€” ishga tushmaydigan "faqat tip" fayli

Avval bitta tushunchani aniqlab olaylik, chunki bob davomida juda ko'p uchraydi. .d.ts β€” bu declaration file (deklaratsiya fayli): ichida faqat tiplar bo'ladi, hech qanday ishga tushadigan kod yo'q. U "filankas funksiya bor, u shunday argument oladi va shunday qiymat qaytaradi" deb e'lon qiladi, lekin funksiyaning tanasini yozmaydi.

Tasavvur qiling: kutubxonaning haqiqiy mantig'i .js faylda yashaydi (brauzer yoki Node shuni ishlatadi), .d.ts esa faqat TypeScript'ga "bu .js faylda nima borligini" tushuntiradigan tip xaritasi. Ikkalasi yonma-yon turadi:

lodash/
  lodash.js      <- haqiqiy kod (ishga tushadi)
  index.d.ts     <- faqat tiplar (TypeScript o'qiydi, tushib qoladi)

πŸ“Œ .d.ts ichida function f(x: number): string; deb yozasiz β€” nuqta-vergul bilan tugaydi, jingalak qavs (tana) yo'q. Bu β€” 17-bobda ko'rgan declare dunyosi: "bu narsa boshqa joyda mavjud, men faqat uning tipini aytyapman". Kompilyatsiyadan keyin .d.ts hech qanday JavaScript chiqarmaydi β€” u faqat tekshiruv uchun.

1-yo'l: kutubxonada tip o'zida bor (built-in)

Eng baxtli holat β€” eng ko'p uchraydigani ham. Zamonaviy kutubxonalarning aksariyati o'z tiplarini o'zida olib keladi. Masalan zod, axios, vite, prisma, date-fns β€” bularni npm install qilsangiz, tiplar avtomatik birga keladi, hech narsa qilish shart emas:

npm install zod
import { z } from "zod";

const KitobShemasi = z.object({
  id: z.number(),
  nomi: z.string(),
});

type Kitob = z.infer<typeof KitobShemasi>;
// { id: number; nomi: string }  β€” to'liq tipli, qo'shimcha hech narsasiz

Bu qanday ishlaydi? Kutubxonaning package.json faylida types (yoki eski nomi typings) maydoni bor, u .d.ts faylga ishora qiladi:

{
  "name": "zod",
  "main": "lib/index.js",
  "types": "lib/index.d.ts"
}

TypeScript import paytida node_modules/zod/package.jsonni o'qiydi, types maydonini ko'radi va o'sha .d.ts faylni topadi. Sizning ishingiz β€” shunchaki import qilish.

πŸ’‘ Yangi paket o'rnatishdan oldin "TypeScript'ni qo'llab-quvvatlaydimi?" deb tekshirishning eng tez yo'li β€” npmjs.com'dagi paket sahifasiga qarash. Agar nom yonida ko'k TS belgisi bo'lsa β€” tip o'zida bor (built-in). DT belgisi bo'lsa β€” tip alohida @types paketda (keyingi bo'lim). Hech qaysi bo'lmasa β€” tip umuman yo'q.

πŸ“Œ Built-in tipni "ishlatish" uchun hech qanday maxsus import yozmaysiz. import { z } from "zod" β€” bu oddiy import, tiplar fonda o'z-o'zidan ulanadi. .d.ts faylni qo'lda import qilish kerak emas β€” bu eng ko'p uchraydigan boshlovchi tushunmovchiligi.

2-yo'l: tip alohida β€” @types va DefinitelyTyped

Endi lodashga qaytaylik. U eski va sof JavaScript kutubxonasi, tipni o'zida olib kelmaydi. Lekin uni TypeScript'da ishlatadiganlar shunchalik ko'pki, jamoa uning tiplarini alohida yozib qo'ygan. Bu tiplar DefinitelyTyped degan ulkan jamoat GitHub repozitoriysida yashaydi va npm'ga @types/... nomi bilan nashr etiladi:

npm install --save-dev @types/lodash

--save-dev (qisqasi -D) β€” bu tip paketi faqat ishlab chiqish vaqtida kerak degani: dasturni brauzer yoki Node ishlatganda tiplar kerak emas (ular kompilyatsiyada tushib qoladi), shuning uchun ular devDependenciesga tushadi. Endi bir narsa o'zgartirmasdan, o'sha import to'satdan to'liq tipli bo'lib qoladi:

import _ from "lodash";

const bo_laklar = _.chunk([1, 2, 3, 4, 5], 2);
// bo_laklar: number[][]  β€” endi aniq tip!

@types/lodash DefinitelyTyped jamoat repozitoriysidan npm orqali keladi va TypeScript uni node_modules/@types ichidan avtomatik topadi

TypeScript @typesni qanday topadi? Bu yerda sehr yo'q: node_modules/@types/ ichidagi hamma paket avtomatik global ko'rinadi, hech qanday qo'shimcha sozlama yozmaysiz. @types/lodashni o'rnatdingizmi β€” import _ from "lodash" darrov tipli bo'ladi. TypeScript paketning JS kodini (lodash) va uning tiplarini (@types/lodash) nom bo'yicha bog'laydi.

πŸ“Œ @types/xni alohida import qilmaysiz. import lodash from "@types/lodash" deb yozsangiz xato bo'ladi β€” @types/lodash ishlatadigan modul emas, faqat tip paketi. Siz baribir import _ from "lodash" deysiz; @types/lodash esa fonda o'sha importga tip ulaydi.

πŸ’‘ Mashhur built-in tipsiz paketlar va ularning @typeslari: @types/node (Node.js o'zi β€” fs, path, process uchun; har Node loyihada deyarli doim kerak), @types/express, @types/jest, @types/react. Birinchi qadamingiz har doim bir xil: import qizil chizilsa va xato Try npm i --save-dev @types/... desa β€” shuni o'rnatib ko'ring.

TypeScript tipni qanday tartibda qidiradi

Yuqoridagi ikki yo'lni TypeScript bitta qidiruv jarayonida birlashtiradi. import x from "paket" yozganingizda, kompilyator tipni shu aniq tartibda qidiradi:

  1. Paketning o'zida tip bormi? β€” node_modules/paket/package.jsondagi types maydoni yoki birga kelgan .d.ts. Bo'lsa β€” tugadi.
  2. node_modules/@types/paket bormi? β€” DefinitelyTyped'dan o'rnatilgan tip paketi. Bo'lsa β€” tugadi.
  3. Loyihangizda o'z .d.ts faylingiz bormi? β€” declare module "paket" (keyingi bo'lim). Bo'lsa β€” tugadi.
  4. Hech qaysi bo'lmasa β€” TS7016 xato: "tip topilmadi".

import paytida TypeScript tipni qidirish tartibi: avval paketning o'z d.ts, keyin node_modules/@types, keyin o'z deklaratsiyangiz, topilmasa TS7016 xato

Bu tartibni bilish muammoni tezda hal qilishga yordam beradi: import qizil chizildimi β€” o'zingizdan so'rang "qaysi bosqichda to'xtadi?". Odatda javob 2-bosqich: @typesni o'rnatish kifoya. Kamdan-kam hollardagina 3-bosqichgacha β€” o'z deklaratsiyangizni yozishgacha β€” borishingizga to'g'ri keladi.

3-yo'l: tip umuman yo'q β€” declare module

Ba'zan kutubxona shunchalik eski yoki kichikki, na o'zida tip bor, na @types/... paketi mavjud. U holda npm install @types/... xato beradi ("paket topilmadi"), import esa baribir TS7016 chiqaradi. Bu β€” oxirgi chora: tipni o'zingiz yozasiz.

Eng tez yechim β€” loyihada bitta .d.ts fayl yaratib (masalan tiplar.d.ts yoki globals.d.ts), unga bo'sh declare module yozish:

// tiplar.d.ts
declare module "eski-kutubxona";

Bu "shorthand" (qisqartirilgan) deklaratsiya. Endi eski-kutubxonani import qilsa bo'ladi, lekin uning hammasi any bo'ladi:

import eski from "eski-kutubxona";

const natija = eski.istalganNarsa(1, 2, 3); // natija: any β€” xato bermaydi

βœ… Bu kompilyatsiyadan o'tadi. Lekin diqqat: any β€” bu "TypeScript bu yerda tekshirmaydi" degani (9-bobni eslang). Siz xato yozsangiz ham aytmaydi. Bu β€” tez, lekin xavfsizligi past yechim. "Ishlasin, hozir tip yozishga vaqtim yo'q" holatlari uchun.

πŸ“Œ declare module "x"; (tanasiz, qisqa shakl) faqat alohida .d.ts faylda ishlaydi. Uni oddiy .ts faylga (ichida import/export bo'lgan modul fayliga) yozsangiz, TypeScript TS2664: Invalid module name in augmentation xatosini beradi. Qoida: ambient (atrof-muhit) deklaratsiyalar β€” .d.ts faylga.

To'liq tiplangan declare module

anydan ko'ra yaxshiroq variant β€” kutubxonaning haqiqiy shaklini declare module ichida tasvirlash. Faqat o'zingiz ishlatadigan qismini yozsangiz ham bo'ladi:

// sodda-slug.d.ts
declare module "sodda-slug" {
  // Standart (default) eksport: funksiya
  export default function slugla(matn: string): string;
  // Nomli eksportlar:
  export function tozala(matn: string): string;
  export const versiya: string;
}

Endi import to'liq tipli:

import slugla, { tozala, versiya } from "sodda-slug";

const s: string = slugla("Salom Dunyo"); // βœ… string
const t: string = tozala("  bo'sh  ");    // βœ… string
console.log(s, t, versiya);

Va endi noto'g'ri ishlatsangiz β€” xato chiqadi, xuddi haqiqiy tipli kutubxonadagidek:

import slugla from "sodda-slug";

const n: number = slugla("Salom");
// ❌ Xato: Type 'string' is not assignable to type 'number'.

πŸ’‘ Hamma narsani yozish shart emas. declare module ichida faqat o'zingiz haqiqatan ishlatadigan funksiyalarni yozing. Kutubxonada 50 ta funksiya bo'lsa-yu, siz 3 tasini ishlatsangiz β€” o'sha 3 tasini yozasiz. Keyinroq yana kerak bo'lsa, qo'shasiz. Bu β€” "etarli darajada tip" yondashuvi.

Mavjud modulga tip qo'shish: augmentation

Ba'zan kutubxonaning tiplari bor, lekin u yangilik qo'shgan-u, @types hali yangilanmagan; yoki siz kutubxonaga o'z plaginingizni ulagansiz. Bunday holatda butun modulni qaytadan yozmay, mavjud tiplarga qo'shimcha kiritasiz. Bu β€” module augmentation (modulni kengaytirish):

// augment.d.ts
import "sodda-slug"; // avval modulni "olib kelamiz"

declare module "sodda-slug" {
  // Mavjud tiplarni ALMASHTIRMAYMIZ, ustiga yangi a'zo QO'SHAMIZ:
  export function teskari(matn: string): string;
}

Endi teskari ham xuddi kutubxonaning o'z funksiyasidek import qilinadi:

import slugla, { teskari } from "sodda-slug";

const a: string = slugla("Salom");
const b: string = teskari("Salom"); // βœ… augmentation orqali qo'shildi

πŸ“Œ Augmentation va qaytadan yozish farqi yuqoridagi birinchi qatorda: import "sodda-slug"; bo'lsa β€” TypeScript "bu modul allaqachon bor, men unga qo'shyapman" deb tushunadi. Bu qator bo'lmasa β€” modulni noldan e'lon qilyapsiz deb o'ylaydi.

πŸ’‘ Xuddi shu usul bilan global obyektlarga ham tip qo'shasiz β€” masalan windowga o'z xossangizni. Buni declare global bilan qilamiz (17-bobda ko'rgansiz):

// global.d.ts
export {}; // faylni modul qilish uchun (aks holda declare global ishlamaydi)

declare global {
  interface Window {
    myApp: { versiya: string; sozlamalar: Record<string, string> };
  }
}
window.myApp = { versiya: "1.0", sozlamalar: { til: "uz" } };
const v: string = window.myApp.versiya; // βœ… endi tipli, xato yo'q

skipLibCheck β€” kutubxona tiplaridagi xatolarni e'tiborsiz qoldirish

Vaqti-vaqti bilan kutubxonaning .d.ts faylining o'zida xato bo'ladi β€” masalan, ikki kutubxona bir-biriga zid tip e'lon qiladi yoki @types paketi eskirgan. Bunday holatda kompilyator sizning kodingizda emas, node_modules ichidagi begona .d.tsda xato ko'rsatadi:

node_modules/buzuq-paket/index.d.ts(3,20): error TS2304: Cannot find name 'NomavjudTip'.

Bu sizning aybingiz emas va siz uni tuzata olmaysiz β€” fayl begona kutubxonaniki. Aynan shu holat uchun tsconfig.jsonda skipLibCheck bor:

{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

skipLibCheck: true β€” "barcha .d.ts fayllarning ichini tekshirma" degani. TypeScript baribir o'sha tiplardan foydalanadi (sizning kodingiz to'liq tipli qoladi), lekin .d.ts fayllarning o'z ichidagi muammolarni tekshirib o'tirmaydi. Yuqoridagi buzuq paket xatosi skipLibCheck bilan butunlay yo'qoladi.

πŸ“Œ skipLibCheck faqat .d.ts fayllar ichini tekshirmaydi. Sizning .ts kodingiz baribir to'liq tekshiriladi β€” bu sozlama sizning xatolaringizni yashirmaydi, faqat kutubxonalardagi tip xatolarini o'tkazib yuboradi.

πŸ’‘ Amalda ko'p loyiha skipLibCheck: true bilan ishlaydi, chunki u kompilyatsiyani ham tezlashtiradi (minglab .d.ts faylni qayta tekshirmaydi). Ko'plab boshlang'ich shablonlar (Vite, Next.js) buni default yoqib qo'yadi. Faqat bitta xavfi bor: o'zingiz yozgan .d.tsdagi xato ham yashirinib qolishi mumkin β€” shuning uchun uni "muammoni yashirish" emas, "begona kutubxona muammosini chetlab o'tish" deb biling.

Kutubxona tiplarini o'qish β€” go-to-definition

Tashqi kutubxonani ishlatayotganda eng kerakli ko'nikma β€” uning tiplarini o'qiy olish. Funksiya qanday argument oladi? Nima qaytaradi? Buni hujjatga qaramay, to'g'ridan-to'g'ri tipdan bilib olish mumkin. Muharriringizda (VS Code) funksiya nomi ustiga kursorni qo'ying β€” to'liq imzo (signature) ko'rinadi. Yoki nom ustida F12 (Go to Definition) bossangiz β€” bevosita o'sha .d.ts faylga olib boradi:

import { z } from "zod";
// z.object ustida F12 bossangiz -> zod/lib/types.d.ts ga olib boradi,
// u yerda object metodining aniq tipi va qaytaradigan qiymati ko'rinadi.

πŸ’‘ Bu β€” TypeScript'ning eng kuchli, lekin kam baholanadigan tarafi. Kutubxona tiplari aslida o'qiladigan hujjat: function chunk<T>(array: T[], size?: number): T[][] degan bitta qator sizga chunkning massiv olishini, ixtiyoriy size qabul qilishini va massivlar massivini qaytarishini hujjat o'qimasdan aytib beradi. Yangi kutubxona o'rganayotganda .d.tsga "kirib chiqish" odat qiling.

πŸ“Œ .d.ts ichidagi ? (ixtiyoriy parametr, 6-bob), generic <T> (11-bob), union | (7-bob) β€” bularning hammasi siz allaqachon o'rgangan tushunchalar. Kutubxona tiplari sizga begona til emas: ular shu kitobdagi aynan o'sha qurilmalardan yasalgan. Shuning uchun ularni o'qiy olasiz.

Versiya mosligi: paket va @types

Bir nozik nuqta: lodash va @types/lodash β€” bu ikki alohida paket, ularning versiyalari alohida yangilanadi. Odatda DefinitelyTyped versiyani kutubxonaga moslashtiradi: @types/lodash@4.x β€” lodash@4.x uchun. Lekin ba'zan ular bir-biridan orqada qoladi.

Belgilar: - Kutubxonaning yangi funksiyasini ishlatmoqchisiz, lekin TypeScript "bunday a'zo yo'q" deydi β€” @types eski bo'lishi mumkin. npm update @types/... bilan yangilang. - Yoki teskari: @types yangiroq versiyani tasvirlaydi, siz esa kutubxonaning eski versiyasini o'rnatgansiz β€” tip bor deydi-yu, ishga tushganda funksiya yo'q. Bu xavfliroq, chunki kompilyatsiya o'tadi, lekin runtime'da uziladi.

πŸ“Œ Qoidasi: lodashni 4.17 o'rnatdingizmi, @types/lodashni ham 4.x ichida ushlang. Major versiya (4.x, 5.x) mos kelishi muhim. Kichik farqlar (4.17 va 4.14) odatda zararsiz, lekin yangi funksiya ishlatayotganda diqqat qiling.

πŸ’‘ Modern paketlarning ko'pi (zod, axios...) tipni o'zida olib kelgani uchun bu muammo umuman bo'lmaydi: tip va kod bir paketda, bir versiyada β€” hech qachon mos kelmay qolmaydi. Bu β€” built-in tipning yana bir afzalligi.

O'z paketingizga tip qo'shish β€” siz kutubxona yozsangiz

Endi teskari tomon. Aytaylik, o'zingiz npm'ga kutubxona nashr qilmoqchisiz va uni TypeScript'da ham, JavaScript'da ham ishlatsa bo'lsin deysiz. Sizning paketingiz ham yuqoridagi 1-yo'l ("built-in tip") bo'lishi kerak β€” ya'ni .d.ts faylni paketga qo'shib, package.jsonda types maydonida ko'rsatasiz:

{
  "name": "mening-paketim",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts"
}

types maydoni β€” bu kutubxonangizdan foydalanadigan har bir TypeScript dasturchi uchun "tip shu yerda" degan ishora. TypeScript import paytida aynan shu maydonni o'qiydi (qidirish tartibining 1-bosqichi).

.d.ts faylni qo'lda yozish shart emas β€” agar paketingizni TypeScript'da yozsangiz, tsconfig.jsonda "declaration": true qo'ysangiz, kompilyator har .ts fayl yoniga mos .d.ts faylni o'zi yaratadi:

{
  "compilerOptions": {
    "declaration": true,
    "outDir": "dist"
  }
}

πŸ“Œ Zamonaviy paketlarda types o'rniga (yoki bilan birga) exports maydoni ham ishlatiladi β€” u har bir kirish nuqtasi uchun alohida tip va kod yo'lini ko'rsatishga imkon beradi. Boshlovchi uchun main + types kifoya; exportsni kutubxonangiz murakkablashganda o'rganasiz.

πŸ’‘ Agar siz paketni JavaScript'da yozayotgan bo'lsangiz ham TypeScript foydalanuvchilarini xursand qila olasiz: qo'lda bitta index.d.ts yozib, package.jsonda types da ko'rsating. Shunday qilib JS kutubxonangiz "TypeScript-do'st" bo'ladi va npmjs'da ko'k TS belgisini oladi.

Hammasini bir joyda: amaliy oqim

Yangi kutubxona o'rnatganda har safar shu tartibni bosib o'ting:

  1. npm install paket β€” o'rnating va import qilib ko'ring.
  2. Import qizil chizilmadimi? β€” Tabriklayman, tip o'zida bor (1-yo'l). Hech narsa qilish kerak emas.
  3. Qizil chizildi va xato Try npm i --save-dev @types/... desa β€” o'sha buyruqni ishga tushiring (2-yo'l). Ko'pincha shu yetadi.
  4. @types/... paketi topilmasa ("404") β€” o'zingiz declare module yozing (3-yo'l): tez kerak bo'lsa bo'sh shorthand bilan, vaqtingiz bo'lsa to'liq tiplab.
  5. node_modules ichidagi begona .d.tsda xato chiqsa β€” tsconfig.jsonga skipLibCheck: true qo'shing.

Bu besh qadam real loyihalardagi tip muammolarining deyarli barchasini hal qiladi. Eng muhimi shuni eslab qoling: TypeScript hech qachon "sehrli" emas β€” u faqat .d.ts fayllardagi yozilgan tiplarni o'qiydi. Tip qayerdandir kelishi kerak: kutubxonaning o'zidan, @typesdan yoki sizning qo'lingizdan.

21-bob mashqlari

Quyidagi mashqlarni o'zingiz bajaring. Tashqi paket talab qiladigan mashqlar uchun kichik test loyiha (npm init -y) yarating va tsc --noEmit --strict bilan tekshiring; declare module mashqlarini esa alohida .d.ts faylga yozing.

  1. Bo'sh loyiha yarating va import _ from "lodash" yozing. Chiqqan xato xabarini (TS7016 yoki TS2307) izoh sifatida ko'chiring va qaysi raqamli xato ekanini yozing.
  2. Built-in tipli kutubxona (zod) o'rnating, z.object({ id: z.number() }) bilan kichik shema yarating va undan z.infer orqali tip oling. Hech qanday @types o'rnatmasdan ishlaganini tasdiqlang.
  3. @types/lodash ni o'rnating, _.chunk([1,2,3,4], 2) natijasining tipini hover bilan ko'ring va izohda yozing (number[][]).
  4. @types/lodashni o'rnatgach, _.chunkka noto'g'ri argument (_.chunk(5, 2) β€” birinchi argument massiv emas) bering va xato chiqishini tasdiqlang.
  5. .d.ts fayl yarating va unda bo'sh shorthand declare module "qandaydir-paket"; yozing. Shu paketni import qilib, undan biror narsa olib any ekanini (hover bilan) tasdiqlang.
  6. 5-mashqdagi paketdan olingan qiymat any bo'lgani uchun istalgan amalni (x.istalgan.narsa()) xatosiz yozib ko'ring. Bu nima xavf tug'dirishini izohda yozing.
  7. To'liq tiplangan declare module "matn-vositasi" yozing: ichida export default function teskarila(s: string): string; bo'lsin. Import qilib, natija string ekanini tekshiring.
  8. 7-mashqdagi modulga qaytgan stringni numberga belgilashga urining (const n: number = teskarila("a")) va xato chiqishini izohga ko'chiring.
  9. To'liq declare modulega nomli eksport qo'shing: export function uzunlik(s: string): number;. Uni { uzunlik } bilan import qilib ishlating.
  10. Module augmentation yozing: avval import "matn-vositasi";, keyin declare module "matn-vositasi" { export function bo_yi(s: string): number; }. Yangi bo_yi funksiyasi import qilinishini tasdiqlang.
  11. 10-mashqda boshidagi import "matn-vositasi"; qatorini olib tashlang va nima o'zgarishini kuzating (augmentation emas, qayta e'lon bo'lib qoladi). Farqni izohda yozing.
  12. declare global bilan Window interface'iga sozlama: { til: string } xossasini qo'shing. window.sozlama.til ni xatosiz o'qib ko'ring. (.d.ts fayl boshida export {}; borligiga ishonch hosil qiling.)
  13. 12-mashqda export {}; qatorini olib tashlang va declare global xato bera boshlaganini ko'ring; xatoni izohga yozib, qatorni qaytaring.
  14. Ataylab buzuq .d.ts yarating: ichida export const x: MavjudEmasTip;. Uni import qiladigan kod yozib, TS2304 xatosi chiqishini tasdiqlang.
  15. tsconfig.jsonga "skipLibCheck": true qo'shib, 14-mashqdagi buzuq .d.ts xatosi yo'qolganini tekshiring. Sizning .ts kodingiz baribir tekshirilishini bir xato yozib (const y: number = "matn") isbotlang.
  16. Bir package.json yozing va unga "types": "dist/index.d.ts" maydonini qo'shing. Bu maydon nima vazifa bajarishini izohda 2 jumlada tushuntiring.
  17. Kichik TypeScript fayl (index.ts) yozib, tsconfig.jsonda "declaration": true qo'ying va tsc ishga tushiring. Yoningizda yaratilgan index.d.ts ichida nima borligini ko'ring va izohlang.
  18. Kutubxona tiplarini o'qish mashqi: zod (yoki boshqa built-in tipli paket) funksiyasi ustida muharriringizda "Go to Definition" (F12) bosing va olib borgan .d.ts fayldan bitta funksiya imzosini izohga ko'chiring.
  19. Versiya mosligi mashqi: lodash va @types/lodashning package.json'larini oching, ikkalasining versionini solishtirib izohga yozing. Major versiyalar mos kelishini tekshiring.
  20. To'liq oqim mashqi: yangi tashqi paket tanlang (masalan dayjs β€” built-in tipli yoki validator β€” @types kerak). 1-yo'lmi, 2-yo'lmi aniqlang, kerak bo'lsa @typesni o'rnating va paketning bitta funksiyasini to'liq tipli holda ishlatib ko'ring. Bosib o'tgan qadamlaringizni izohda yozing.