IlmHamroh
JavaScript Full-stack/15-qism. TypeScript36/47-dars16 daqiqa
Mundarija (30)

TypeScript declaration fayllari (.d.ts): JavaScript kodga tur "kiyimi"

Qisqacha: .d.ts (e'lon fayli) — kodsiz, faqat turlardan iborat fayl: "bu funksiya bor va shunday imzoga ega, lekin kodi boshqa joyda". U turlarsiz JavaScript kutubxonaga "kiyim" kiydiradi, brauzerda bor-u lib.dom da yo'q global obyektlarni tasvirlaydi va tsc --declaration bilan o'z kodingizdan avtomatik yaratiladi. .d.ts — faqat va'da: unda yozilgan narsa ishlash paytida haqiqatan borligini TypeScript tekshirmaydi.

Bu darsda

  • TS7016 ("Could not find a declaration file") xatosini tushunasiz va JS modul yoniga .d.ts yozib tuzatasiz.
  • declare kalit so'zi ma'nosini ("bor, lekin bu yerda emas") tushuntirasiz.
  • Global o'zgaruvchi va brauzer API'sini .d.ts bilan tasvirlaysiz: skript fayl va declare global.
  • declare module "*.svg" qanday ishlashini va qayerda yozilishini bilasiz.
  • tsc --declaration bilan o'z modulingizdan .d.ts yaratasiz.

Oldin bilishingiz kerak: Modullar TypeScript'da, Kengaytirish, kesishma va declaration merging, JSDoc va // @ts-check.

1. Nega bu kerak?

O'tgan darsda modullar orasidagi tur importlarini ko'rdik. Endi savol: import qilinayotgan fayl JavaScript bo'lsa-chi? Turlari yo'q, uni TypeScript'ga qayta yozish esa imkonsiz yoki keraksiz.

«Bahor» kassasida yillar oldin yozilgan kichik kutubxona bor — som.js. U summani chiroyli ko'rinishga keltiradi va hamma yerda ishlatiladi:

js
// vendor/som.js — eski kutubxona (JavaScript, turlarsiz)
export function formatSom(amount, withCurrency = true) {
  const digits = String(Math.round(amount));
  const text = digits.replace(/\B(?=(\d{3})+$)/g, " ");
  return withCurrency ? `${text} so'm` : text;
}

Sardor yangi receipt.ts da uni import qildi. npx tsc:

text
36-dts/receipt.ts(2,37): error TS7016: Could not find a declaration file for module './vendor/som.js'. '…/36-dts/vendor/som.js' implicitly has an 'any' type.

Tarjimasi: "./vendor/som.js moduli uchun e'lon fayli topilmadi. som.js yashirincha any turini oldi". (Sizda … o'rnida papkangizning to'liq manzili turadi.) TypeScript .js faylni topdi, lekin uning ichiga qaramaydi (allowJs yo'q) — demak, formatSom nima qabul qilishini bilmaydi. strict esa yashirin any ga ruxsat bermaydi.

Ikki yo'l bor. Birinchisi — som.js ni .ts ga ko'chirish. Lekin bu birovning kodi, u boshqa loyihalarda ham ishlatiladi, unga tegmaslik kerak. Ikkinchisi — uning yoniga faqat turlarni yozib qo'yish. Bu .d.ts.

2. .d.ts va declare

2.1 Birinchi e'lon fayli

som.js ning yoniga, xuddi shu nom bilan, som.d.ts:

ts
// vendor/som.d.ts — som.js uchun tur "kiyimi" (kodsiz)
/** 35000 → "35 000 so'm"; withCurrency: false → "35 000" */
export declare function formatSom(
  amount: number,
  withCurrency?: boolean,
): string;

/** "35 000 so'm" → 35000; raqam bo'lmasa — null */
export declare function parseSom(text: string): number | null;

export declare const VERSION: string;

Endi npx tsc — toza, TS7016 yo'qoldi. Bundan tashqari, tur ishlay boshladi: formatSom("35000", "ha") yozsangiz —

text
TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

TypeScript aytyapti: "string turidagi argumentni number turidagi parametrga berib bo'lmaydi". som.js ichiga qaramasdan — faqat som.d.ts dagi imzoga qarab.

Kunlik o'xshatish: dori qutisidagi yo'riqnoma. Dorining o'zi (kod) — qutida, yo'riqnoma (.d.ts) — "kuniga ikki marta, ovqatdan keyin". Shifokor yo'riqnomani o'qib, dorini to'g'ri buyuradi — dorining kimyoviy tarkibiga qaramasdan.

2.2 tsc .d.ts ni qanday topadi

import … from "./vendor/som.js" ni ko'rganda tsc shunday qidiradi:

Qadam Qidiradi Natija
1 som.ts yo'q
2 som.d.ts bor — turlar shu yerdan
3 som.js (allowJs bo'lsa) qaralmaydi — .d.ts topildi

.d.ts .js dan oldin topiladi. TypeScript'ni o'rnatish darsidagi vendor/web-vitals.d.ts aynan shu sabab bilan yozilgan edi: u bor bo'lsa, tsc vendor .js ni dasturga olmaydi va dist/ ga qayta formatlab yozmaydi. Ishlash paytida esa Node (yoki brauzer) som.js ni yuklaydi — .d.ts haqida umuman bilmaydi.

flowchart LR
  A["receipt.ts: import ./vendor/som.js"] --> B["tsc"]
  A --> C["Node / brauzer"]
  B --> D["som.d.ts — turlar"]
  C --> E["som.js — kod"]
  D --> F["tekshiruv: formatSom(number)"]
  E --> G["ishlash: 35 000 so'm"]

2.3 declare — "bor, lekin bu yerda emas"

declare kalit so'zi kompilyatorga aytadi: "bu nom ishlash paytida mavjud bo'ladi, men faqat uning turini aytyapman". Ambient (atrofdagi) e'lon deyiladi: qiymat "atrofda" — boshqa faylda, brauzerda, build vositasida.

declare dan keyin tana yoki boshlang'ich qiymat yozib bo'lmaydi:

ts
declare function tax(n: number): number { return n * 0.12; }
declare const RATE: number = 0.12;

Kompilyator:

text
TS1183: An implementation cannot be declared in ambient contexts.
TS1039: Initializers are not allowed in ambient contexts.
  • TS1183: "Ambient kontekstda amalga oshirish (tana) e'lon qilib bo'lmaydi".
  • TS1039: "Ambient kontekstda boshlang'ich qiymatga ruxsat yo'q".

declare — faqat imzo. .d.ts faylda hamma narsa avtomatik ambient: u yerda kod yozib bo'lmaydi.

Tekshirib ko'ring: som.d.ts da parseSom natijasini number deb yozsangiz (| null siz), tsc xato beradimi?

Javob

Bermaydi. tsc .d.ts ni som.js bilan solishtirmaydi — u .js ichiga qaramaydi. Natijada readAmount null ni tekshirmasdan qaytaradi va xato ishlash paytiga ko'chadi. .d.ts ning to'g'riligi — uni yozgan odamning mas'uliyati. Bu darsning asosiy tuzog'i, pastda batafsil.

3. Global narsalarni tasvirlash

3.1 Skript .d.ts — global e'lonlar

.d.ts faylda import/export bo'lmasa, u skript hisoblanadi: undagi hamma e'lon global — har faylda import qilmasdan ko'rinadi. Kanon vazifalar dagi trusted-types.d.ts shunday fayl (TypeScript va DOM qadamida yoziladi). Trusted Types — brauzerda bor (Chrome 83+), lekin TypeScript'ning lib.dom ida yo'q API (XSS va DOM xavfsizligi):

ts
// trusted-types.d.ts (kanondan, boshidagi izohsiz)
interface TrustedScriptURL {
  // Brend: oddiy satr bilan almashib ketmasin — faqat siyosatdan
  readonly __trustedScriptURL: unique symbol;
}

interface TrustedTypePolicy {
  createScriptURL(url: string): TrustedScriptURL;
}

interface TrustedTypePolicyFactory {
  createPolicy(
    nomi: string,
    qoidalar: { createScriptURL?: (url: string) => string },
  ): TrustedTypePolicy;
}

// Trusted Types bo'lmagan brauzerda (Firefox) — undefined.
// var — globalThis.trustedTypes bo'lishi uchun (let/const bo'lmaydi)
// eslint-disable-next-line no-var
declare var trustedTypes: TrustedTypePolicyFactory | undefined;

// Declaration merging: lib.dom dagi interfeysga yangi overload
// qo'shiladi — register() siyosatdan o'tgan manzilni ham qabul qiladi
interface ServiceWorkerContainer {
  register(
    manzil: string | URL | TrustedScriptURL,
    sozlama?: RegistrationOptions,
  ): Promise<ServiceWorkerRegistration>;
}

Bu bitta faylda uch dars uchrashadi:

  • __trustedScriptURL: unique symbol — Branded types dagi tamg'a: oddiy satrni xavfsiz manzil o'rniga berib bo'lmaydi.
  • declare var trustedTypes — global o'zgaruvchi; var — globalThis ning xususiyati bo'lishi uchun, | undefined — Firefox'da yo'qligi uchun.
  • interface ServiceWorkerContainer — lib.dom dagi interfeysga yangi metod imzosi qo'shiladi (declaration merging). Skript faylda bo'lgani uchun u global interfeys bilan birlashadi.

3.2 Modul ichida: declare global

Fayl modul bo'lsa (unda import/export bor), undagi e'lonlar mahalliy. Global narsa qo'shish uchun declare global { … } bloki:

ts
declare global {
  var BAHOR_VERSION: string;
}
globalThis.BAHOR_VERSION = "5.0";
console.log(BAHOR_VERSION); // 5.0

declare global faqat modul faylda ishlaydi. Skript faylda u ma'nosiz — u yerda hamma narsa allaqachon global. tsc buni shunday aytadi (skript faylda sinadik):

text
a.ts(1,9): error TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.

"Global sohani kengaytirish faqat modullar yoki ambient modul e'lonlari ichida bo'lishi mumkin". Qoida oddiy: skript .d.ts — to'g'ridan-to'g'ri declare var; modul fayl — declare global { var … }.

3.3 TypeScript ushlamaydigan tuzoq: declare — faqat va'da

ts
declare const BAHOR_BUILD: string;
console.log(BAHOR_BUILD.length);

tsc — xatosiz. Node esa:

text
ReferenceError: BAHOR_BUILD is not defined

declare const "bu o'zgaruvchi bor" dedi va tsc ishondi. Node turlarni o'chirdi — declare qatori butunlay yo'qoldi. BAHOR_BUILD ni hech kim yaratmagan. Bunday global nomlarni odatda build vositasi kodga qo'yadi (Vite'dagi define — 16-qism). Vosita sozlanmagan bo'lsa — ReferenceError.

som.d.ts da ham xuddi shunday: formatSom(amount: number, withCurrency?: boolean) deb yozdik — lekin som.js haqiqatan shunday ishlaydimi, tsc tekshirmaydi. Kutubxona yangilanib, parametrlar tartibi o'zgarsa, .d.ts jim yolg'on gapira boshlaydi. Himoya: .d.ts yozgan modulingizga testlar — ular haqiqiy .js ni chaqiradi (mashqdagi kabi).

4. declare module: fayl bo'lmagan modullar

4.1 Rasm va CSS importlari

Vite kabi bundler'lar (16-qism) rasmni ham "import" qilishga ruxsat beradi: import logo from "./logo.svg" — natija rasm manzili. tsc uchun esa .svg — modul emas:

text
svg.ts(1,18): error TS2307: Cannot find module './logo.svg' or its corresponding type declarations.

"./logo.svg moduli yoki uning tur e'lonlari topilmadi". Yechim — joker belgili (wildcard) modul e'loni: ".svg bilan tugaydigan har qanday import — standart eksporti satr bo'lgan modul":

ts
// assets.d.ts — skript fayl (import/export yo'q)
declare module "*.svg" {
  const url: string;
  export default url;
}

Bu fayl bilan import logo from "./logo.svg" — tsc dan o'tdi, logo — string. Vite shablonlari aynan shunday faylni tayyor beradi (vite/client turlari).

4.2 declare module ni modul ichida yozish

Bitta muhim nozik joy — declare module "*.svg" skript faylda bo'lishi kerak. Modul faylda (yoki saytdagi bloklar kabi har fayl modul bo'lganda) u boshqa ma'noga ega bo'ladi:

ts
declare module "*.svg" {
  const url: string;
  export default url;
}

Kompilyator:

text
TS2664: Invalid module name in augmentation, module '*.svg' cannot be found.

"Kengaytmadagi modul nomi noto'g'ri, *.svg moduli topilmadi". Modul fayl ichida declare module "x" — "mavjud x modulini kengaytir" (module augmentation) degani. *.svg degan mavjud modul yo'q. Kengaytirish — keyingi darsning mavzusi; yangi modul e'lon qilish uchun esa fayl skript bo'lishi shart.

5. tsc --declaration: .d.ts ni avtomatik yaratish

O'z kodingiz uchun .d.ts ni qo'lda yozmaysiz — tsc uni .ts dan chiqaradi. O'rnatish darsida dist/index.d.ts paydo bo'lgani shundan edi (tsc --init "declaration": true ni yoqadi). Mashqdagi receipt.ts uchun (natija turlari yozilmagan funksiyalar bilan):

bash
npx tsc 36-dts/receipt.ts --ignoreConfig --declaration \
  --emitDeclarationOnly --module nodenext --outDir 36-dts/types

--ignoreConfig — papkada tsconfig.json bor, bitta faylni berish uchun kerak (tsconfig.json chuqur darsidagi qoida). Natija — 36-dts/types/receipt.d.ts:

ts
export type Line = {
    readonly dish: string;
    readonly price: number;
};
export declare function receiptLine(line: Line): string;
export declare function totalOf(lines: readonly Line[]): string;
export declare function readAmount(input: string): number;

Funksiya tanalari yo'qoldi, qolgani — imzolar. receiptLine va totalOf natija turi kodda yozilmagan edi — tsc uni chiqardi (string) va .d.ts ga yozdi. .d.ts — modulning "ommaviy shartnomasi": boshqa dastur yoki boshqa jamoa sizning kodingizni faqat shu orqali ko'radi.

Qachon kerak? Kutubxona yozganingizda (npm'ga chiqarishda .js + .d.ts birga ketadi — keyingi dars) va katta loyihalarda tezlik uchun (project references — Build: tsc, bundler'lar darsida). Ilova kodida (vazifalar) — kerak emas, shuning uchun u yerda declaration yoqilmagan.

Tekshirib ko'ring: --declaration bilan yaratilgan .d.ts ga qarab, funksiya ichida xato bor-yo'qligini bilib bo'ladimi?

Javob

Yo'q. .d.ts da faqat imzolar — tana yo'q. Bu uning maqsadi: foydalanuvchiga nima qilishini aytadi, qanday qilishini emas. Funksiya ichidagi xatoni faqat manba .ts ni tekshirish yoki testlar topadi.

6. .d.ts va JSDoc: ikki yo'l bilan bitta maqsad

JSDoc va // @ts-check darsida JavaScript faylga turlarni izoh sifatida yozgan edingiz: /** @param {number} amount */. Bu ham som.js ga tur berishning bir yo'li. Qaysi biri yaxshi?

JSDoc (.js ichida) .d.ts (alohida fayl)
Kodni o'zgartirish kerakmi ha — izohlar qo'shiladi yo'q — .js ga tegilmaydi
Tur va kod mosligi @ts-check bilan tekshiriladi tekshirilmaydi
Qachon tanlanadi kod sizniki, JS'da qoladi kod birovniki yoki o'zgartirib bo'lmaydi

som.js — "vendor" kod, unga tegmaymiz: .d.ts to'g'ri tanlov. vazifalar da esa 12-qismda o'z modullarimizga JSDoc yozgan edik — ular bizniki edi. Ikkalasi bir loyihada yonma-yon yashashi ham mumkin: vazifalar da turlar.ts dagi turlar JSDoc'li .js modullarga /** @import { VazifaMalumoti } from "./turlar.ts" */ bilan ulangan edi (type va interface qadami).

6.1 Qachon .d.ts yozmaslik kerak

.d.ts — qo'lda saqlanadigan ikkinchi nusxa. Har nusxa kabi u eskiradi. Shuning uchun:

  • O'z TypeScript kodingizga .d.ts yozmang — tsc --declaration uni o'zi yaratadi va u hech qachon eskirmaydi.
  • npm paketiga — avval tayyor turlarni qidiring: paketning o'zida yoki @types/… da (keyingi dars). Ko'pchilik mashhur paketlar uchun ular bor va minglab odam ularni tekshirgan.
  • O'zingiz yozsangiz — faqat ishlatadigan qismini. som.js da o'nta funksiya bo'lsa-yu, sizga ikkitasi kerak bo'lsa — ikkitasini e'lon qiling. Kichik .d.ts ni to'g'ri saqlash oson.

7. skipLibCheck: .d.ts larni tekshirmaslik

Mashqlar papkamizdagi tsconfig.json da "skipLibCheck": true bor (tsc --init ham uni yozadi). U barcha .d.ts fayllarni (o'zingiznikini ham, node_modules dagilarni ham) ichki xatolar uchun tekshirmaydi. Ular faqat ishlatiladi. Sabab — tezlik va tinchlik: node_modules da yuzlab .d.ts, ularning ichki ziddiyatlari sizning ishingiz emas.

Narxi: o'zingiz yozgan .d.ts dagi xato (masalan, mavjud bo'lmagan turga havola) jim o'tib ketishi mumkin. Shuning uchun o'z .d.ts laringizni kichik va oddiy saqlang, va ularni ishlatadigan kodni testlang.

8. Ko'p uchraydigan xatolar

8.1 JS modulga tur yo'q

TS7016: Could not find a declaration file for module './vendor/som.js'. Tuzatish: yoniga som.d.ts (shu nom bilan). npm paketi bo'lsa — keyingi dars: @types/… yoki declare module.

8.2 declare ga tana yozish

TS1183 / TS1039. Tuzatish: .d.ts va declare — faqat imzo. Kod — .js da.

8.3 Skript faylda declare global

TS2669. Tuzatish: skript .d.ts da — to'g'ridan-to'g'ri declare var; declare global — faqat modulda.

8.4 Modul faylda declare module "*.svg"

TS2664: Invalid module name in augmentation … Tuzatish: e'lonni import/export siz alohida .d.ts ga ko'chiring.

8.5 .d.ts ga ko'r-ko'rona ishonish

ReferenceError yoki noto'g'ri natija — e'lon haqiqatga mos emas. Tuzatish: e'lon qilingan modulni testlang; globalni ishlatishdan oldin typeof X !== "undefined".

9. Mashqlar

1-mashq (oson): Qaysi fayl?

  1. Faqat turlar yoziladigan fayl kengaytmasi: .d.ts. Unda funksiya tanasi bo'ladimi (ha/yo'q)?
  2. import { x } from "./lib.js" — tsc avval lib.d.ts nimi yoki lib.js nimi qidiradi? Kengaytmani yozing (nuqtasiz):
  3. Modul faylda global o'zgaruvchi qo'shish bloki: declare
Yechim

.d.ts — kodsiz, tana yo'q. tsc .d.ts ni .js dan oldin topadi. Modul faylda — declare global { var … }.

2-mashq (o'rta): Brauzer global'i uchun e'lon

«Bahor» saytiga to'lov tizimi skripti <script> bilan ulanadi va global payWidget obyektini yaratadi: payWidget.open(amount: number, orderId: string) — Promise<boolean> qaytaradi (to'landimi). Ba'zan skript yuklanmay qoladi. Skript .d.ts yozing va undan xavfsiz foydalanadigan funksiya yozing.

Yechim
ts
// pay-widget.d.ts — skript fayl (import/export yo'q)
interface PayWidget {
  open(amount: number, orderId: string): Promise<boolean>;
}
// eslint-disable-next-line no-var
declare var payWidget: PayWidget | undefined;
ts
declare var payWidget:
  | { open(amount: number, orderId: string): Promise<boolean> }
  | undefined;

async function pay(
  amount: number,
  orderId: string,
): Promise<boolean> {
  if (typeof payWidget === "undefined") {
    console.warn("To'lov tizimi yuklanmadi");
    return false;
  }
  return payWidget.open(amount, orderId);
}
console.log(typeof pay);
  • | undefined — trustedTypes dagi kabi: global bo'lmasligi mumkin. Usiz payWidget.open tekshiruvsiz chaqirilardi va «declare — faqat va'da» bo'limidagi ReferenceError qaytardi.
  • typeof payWidget === "undefined" — e'lon qilinmagan global uchun ham xavfsiz tekshiruv: ReferenceError bermaydi.
  • Ikkinchi blokda e'lon kod bilan bitta faylda (saytdagi blok uchun) — haqiqiy loyihada u alohida pay-widget.d.ts da turadi.

3-mashq (qiyin): Amaliy tajriba — eski kutubxonaga tur kiyimi

kurs/mashqlar/15/36-dts/ da:

  1. vendor/som.js — darsdagi kutubxona, yana parseSom(text) (raqamlardan son, raqam bo'lmasa — null) va VERSION.
  2. receipt.ts — receiptLine(line) ("Osh....... 35 000 so'm": nom 10 belgigacha nuqta bilan to'ldiriladi, padEnd), totalOf(lines) va readAmount(input) (null bo'lsa — RangeError).

Avval .d.ts siz npx tsc --pretty false ni ishga tushiring. Keyin vendor/som.d.ts yozing, testlarni yozing va receipt.ts uchun .d.ts yarating («tsc --declaration» bo'limidagi buyruq). Ko'rib bo'lgach 36-dts/types/ papkani o'chiring.

Yechim

.d.ts siz — «Nega bu kerak?» bo'limidagi TS7016.

js
// 36-dts/vendor/som.js — eski kutubxona (JavaScript, turlarsiz)
export function formatSom(amount, withCurrency = true) {
  const digits = String(Math.round(amount));
  const text = digits.replace(/\B(?=(\d{3})+$)/g, " ");
  return withCurrency ? `${text} so'm` : text;
}

export function parseSom(text) {
  const digits = text.replace(/\D/g, "");
  return digits === "" ? null : Number(digits);
}

export const VERSION = "1.4.0";

vendor/som.d.ts — «Birinchi e'lon fayli» bo'limidagi fayl. /** … */ izohlar — JSDoc: VS Code ularni formatSom ustida hover'da ko'rsatadi.

ts
// 36-dts/receipt.ts — chek qatorlari
import { formatSom, parseSom } from "./vendor/som.js";

export type Line = { readonly dish: string; readonly price: number };

export function receiptLine(line: Line) {
  return `${line.dish.padEnd(10, ".")} ${formatSom(line.price)}`;
}

export function totalOf(lines: readonly Line[]) {
  return formatSom(lines.reduce((sum, l) => sum + l.price, 0));
}

export function readAmount(input: string): number {
  const value = parseSom(input);
  if (value === null) {
    throw new RangeError(`Summa emas: ${input}`);
  }
  return value;
}

Import "./vendor/som.js" — .js bilan: tsc uning yonidagi som.d.ts ni oladi, Node — som.js ni.

ts
// 36-dts/receipt.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { receiptLine, totalOf, readAmount } from "./receipt.ts";

test("receiptLine: nom va summa", () => {
  const line = receiptLine({ dish: "Osh", price: 35000 });
  assert.equal(line, "Osh....... 35 000 so'm");
});

test("totalOf: jami summa", () => {
  const lines = [
    { dish: "Osh", price: 35000 },
    { dish: "Manti", price: 30000 },
  ];
  assert.equal(totalOf(lines), "65 000 so'm");
});

test("readAmount: matndan summa, bo'sh — RangeError", () => {
  assert.equal(readAmount("28 000 so'm"), 28000);
  assert.throws(() => readAmount("bepul"), RangeError);
});

npx tsc --pretty false — chiqishsiz. node --test 36-dts/receipt.test.ts bizda (Node 24.21.0):

text
✔ receiptLine: nom va summa (4.4223ms)
✔ totalOf: jami summa (1.0336ms)
✔ readAmount: matndan summa, bo'sh — RangeError (2.4148ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 347.0294

Testlar haqiqiy som.js ni chaqiradi — ular som.d.ts dagi va'dalarni tekshiradi. Masalan, som.js da bo'lish belgisi bo'shliq emas, vergul bo'lib qolsa, birinchi test darhol yiqiladi, tsc esa jim qolardi. receipt.ts uchun yaratilgan .d.ts — «tsc --declaration» bo'limidagi natija.

XATOLAR.md ga qo'shing: TS7016, TS1183, TS1039, TS2669, TS2664, TS2307 (.svg importi). Keyin kurs/mashqlar papkasidan:

bash
git add 15/36-dts 15/XATOLAR.md
git commit -m "15/36: som.d.ts — eski JS kutubxonaga tur e'loni"

10. Real ishda

  • node_modules ning yarmi — .d.ts. TypeScript'da yozilgan kutubxonalar npm'ga .js + .d.ts bilan chiqadi. "Go to Definition" ko'pincha sizni .d.ts ga olib boradi — endi uni o'qiy olasiz.
  • lib.dom.d.ts, lib.es2025.d.ts — TypeScript'ning o'zi ham .d.ts lardan iborat (tsconfig.json chuqur dagi lib). Brauzerda bor-u, unda yo'q API — trusted-types.d.ts kabi o'zingiz qo'shasiz.
  • Build vositalari: Vite loyihasidagi vite-env.d.ts — *.svg, *.css va import.meta.env uchun e'lonlar.
  • Eski kod bilan ishlash: turlarsiz ichki kutubxona yoniga .d.ts yozish — JavaScript'dan TypeScript'ga ko'chishning birinchi qadamlaridan (JavaScript'dan TypeScript'ga ko'chish).
  • Intervyu: ".d.ts nima?", "declare nima qiladi?", "Turlarsiz JS kutubxonani qanday ulaysiz?" — amaliy savollar.

Xulosa

  • .d.ts — kodsiz e'lon fayli: JS modul, global yoki brauzer API'sining turlari. tsc uni .js dan oldin topadi.
  • declare — "bor, lekin bu yerda emas": faqat imzo, tana va qiymat yo'q (TS1183, TS1039).
  • Skript .d.ts — global e'lonlar (declare var, declare module "*.svg"); modul faylda — declare global { … }.
  • tsc --declaration o'z kodingizdan .d.ts yaratadi — kutubxona chiqarishda kerak.
  • .d.ts — va'da: tsc uni .js bilan solishtirmaydi. Haqiqatni testlar tekshiradi.

Keyingi dars: Uchinchi tomon kutubxonalarini tiplash — npm paketlarining turlari qayerdan keladi: paketning o'zidan, @types/* dan yoki o'zingiz yozasiz.

Manbalar

  • TypeScript Handbook: "Declaration Files" (Introduction, By Example, Do's and Don'ts) — typescriptlang.org/docs/handbook/declaration-files/introduction.html
  • TypeScript Handbook: "Modules — Reference" (Ambient modules, wildcard module declarations) — typescriptlang.org/docs/handbook/modules/reference.html
  • TSConfig: declaration, emitDeclarationOnly, skipLibCheck — typescriptlang.org/tsconfig
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
TypeScript declaration fayllari (.d.ts): JavaScript kodga tur "kiyimi" — IlmHamroh