IlmHamroh
JavaScript Full-stack/15-qism. TypeScript38/47-dars19 daqiqa
Mundarija (35)

TypeScript build: tsc, bundler'lar va tsgo — tekshirish va JavaScript yozishni ajratish

Qisqacha: tsc ikki ish qiladi: turlarni tekshiradi va JavaScript yozadi. Zamonaviy loyihada bu ishlar ko'pincha bo'linadi: JavaScript'ni tezkor transpiler (esbuild, SWC, Oxc — Vite ichida) yozadi, u turlarni shunchaki o'chiradi va tekshirmaydi; tekshiruvni esa tsc --noEmit alohida qiladi. Katta loyihani tezlashtirish uchun incremental, project references va TypeScript 7 (Go'dagi tsc, avvalgi nomi tsgo) bor.

Bu darsda

  • tsc ning ikki ishini ajrata olasiz va vazifalar da qaysi biri qancha vaqt olishini bilasiz.
  • esbuild bilan .ts faylni JavaScript'ga aylantirasiz va u nega tur xatosini ko'rmasligini tushuntira olasiz.
  • verbatimModuleSyntax (va isolatedModules) nega transpiler bilan ishlaganda kerakligini bilasiz.
  • incremental, project references (tsc -b) va isolatedDeclarations ni sozlaysiz.
  • TypeScript 7 (tsgo) nimani o'zgartirganini va nega hozircha ikki TypeScript paketi kerakligini ayta olasiz.

Oldin bilishingiz kerak: TypeScript'ni o'rnatish va ishga tushirish, tsconfig.json chuqur, Modullar TypeScript'da, Declaration fayllari.

1. Nega bu kerak?

Uchinchi tomon kutubxonalarini tiplash darsida begona kodning turlari bilan ishladik. Endi o'z kodimizni qanday yig'ishga qaytamiz.

vazifalar da npm run build — bu tsc, keyin fayllarni ko'chirish. O'rnatish darsida aytgan edik: tsc bir vaqtda ikki ishni qiladi. Biz vazifalar v5 da (19 ta .ts modul) ikkalasini alohida o'lchadik. Node 24.21.0, Windows, har buyruq 7 marta, mediana:

Buyruq Nima qiladi Vaqt
tsc --noEmit faqat tekshiradi ~0,54 s
tsc (outDir bilan) tekshiradi + .js yozadi ~0,54 s
tsc6 --noEmit (TS 6.0.3) faqat tekshiradi ~1,49 s

Birinchi ikki qatorga qarang: JavaScript yozish deyarli vaqt olmaydi. Hamma vaqt tekshiruvga ketadi. Turlarni o'chirib tashlash — oddiy ish, turlarni tekshirish esa butun dasturni tahlil qilishni talab qiladi.

Kichik loyihada yarim soniya hech narsa emas. Lekin VS Code kabi ulkan loyihada TypeScript 6 bilan to'liq tekshiruv 125,7 soniya olgan. Har faylni saqlaganda ikki daqiqa kutib bo'lmaydi. Shuning uchun dasturchilar ishni ikkiga bo'lishdi: JavaScript'ni tez yozadigan vosita alohida, tekshiruv alohida.

Hayotiy o'xshatish: «Bahor» oshxonasida ikki odam bor. Biri — taomni idishga solib, ofitsiantga uzatadigan qadoqlovchi, u bir zumda ishlaydi. Ikkinchisi — har retseptni tekshiradigan bosh oshpaz, u sekinroq. Mijozni kuttirmaslik uchun qadoqlovchi ishlayveradi, bosh oshpaz esa parallel tekshiradi. Lekin bosh oshpazni umuman olib tashlasangiz — buzuq taom ham chiqib ketadi.

2. tsc ning ikki ishi

2.1 Tekshirish va yozish

O'rnatish darsidagi jadvalni eslang — endi unga yangi qator qo'shiladi:

Vosita Tekshiradimi .js yozadimi
tsc ha ha
tsc --noEmit ha yo'q
node fayl.ts yo'q yo'q, darhol bajaradi
esbuild, SWC, Oxc yo'q ha, juda tez

Oxirgi qator — bugungi dars mavzusi. Bu vositalar transpiler (transpilyatsiya qiluvchi) deyiladi: bir tildagi kodni boshqa tilga yoki boshqa versiyaga o'giradigan dastur. Babel'ni ham 12-qismda shunday atagan edik (JS versiyalari va brauzer mosligi): u yangi JavaScript'ni eskisiga aylantirardi. TypeScript transpiler'i esa turlarni olib tashlaydi.

2.2 Type stripping — transpiler'ning eng oddiy ishi

O'rnatish darsida Node 24 node index.ts ni qanday bajarishini ko'rdik: turlarni o'chiradi va qolganini ishga tushiradi. Transpiler ham aslida shu ishni qiladi, faqat natijani faylga yozadi.

Muhim nuqta: o'chirish uchun turlarni tushunish shart emas. : number — o'chiriladigan matn, uning to'g'ri yoki noto'g'riligi transpiler'ni qiziqtirmaydi. Shuning uchun u har faylni alohida, boshqa fayllarga qaramasdan o'giradi. Tezligining siri ham shunda.

3. Transpiler'lar: esbuild va SWC

3.1 esbuild bilan sinab ko'ramiz

esbuild — Go tilida yozilgan transpiler va bundler (Figma asoschilaridan biri Evan Wallace yozgan). SWC — Rust'da yozilgan transpiler (Next.js uni ishlatadi). Ikkalasi ham npm paketi.

O'rnatish darsidagi xatoni qaytaramiz: choy puli formadan satr bo'lib keldi.

ts
// «Bahor» kassasi: choy puli formadan satr bo'lib keldi
function addTip(total: number, tip: number): number {
  return total + tip;
}
const tip: string = "8000";
console.log(addTip(80000, tip));

tsc darhol to'xtatadi:

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".

Endi shu faylni esbuild 0.28.2 ga beramiz:

bash
npx esbuild@0.28.2 tip.ts --outfile=tip.js
text
  tip.js  107b

Done in 27ms

Chiqish kodi — 0, hech qanday ogohlantirish yo'q. tip.js ichida:

js
function addTip(total, tip2) {
  return total + tip2;
}
const tip = "8000";
console.log(addTip(8e4, tip));

node tip.js — 800008000. Xato natija jim chiqdi, xuddi node tip.ts dagidek.

Natijaga diqqat bilan qarang. Turlar o'chdi, izoh ham yo'qoldi. esbuild parametr nomini tip2 ga o'zgartirdi (tashqaridagi tip bilan to'qnashmasin deb) va 80000 ni qisqaroq 8e4 qilib yozdi. Xulq bir xil. Bu fayl o'qish uchun emas, bajarish uchun — xuddi vazifalar dagi dist/ kabi.

3.2 Nega bunchalik tez

vazifalar v5 ning o'sha 19 moduli bilan o'lchadik (har vosita 7 marta, mediana):

vazifalar v5 (19 modul): bitta ishga tushirish vaqti
  • tsc 6.0.3 --noEmitfaqat tekshiradi1 486 ms
  • tsc 7.0.2 --noEmitfaqat tekshiradi542 ms
  • tsc 7.0.2 (emit)tekshiradi + yozadi538 ms
  • SWC 1.16.13faqat yozadi344 ms
  • esbuild 0.28.2faqat yozadi181 ms
  • node -e 1bo'sh jarayon99 ms

Manba: O'lchandi: vazifalar v5, Node 24.21.0, Windows 11, 7 marta, mediana, 2026-10-06

Oxirgi ustun — hech narsa qilmaydigan node -e 1. Taxminan 0,1 soniya — jarayonni ishga tushirishning o'zi. Demak esbuild'ning haqiqiy ishi — taxminan 0,08 soniya, tsc 7 niki — 0,4 soniyadan ko'proq. Bunday kichik loyihada raqamlar shovqinli, nisbatga qarang: transpiler tekshiruvdan bir necha baravar tez. Kodni ko'paytirgan sari bu farq o'sib boradi.

SWC sozlamasiz eski JavaScript (ES5) uchun yozadi va yordamchi funksiyalar qo'shadi — shuning uchun esbuild'dan sekinroq chiqdi. Haqiqiy loyihada unga target beriladi.

3.3 Fayl-fayl o'girishning sharti: verbatimModuleSyntax

Transpiler har faylni alohida ko'radi. Bu tezlik beradi, lekin bitta muammo tug'diradi. Mana bu importga qarang:

ts
// @ts-options: {"verbatimModuleSyntax": true}
import { IncomingHttpHeaders } from "node:http";

function logAgent(headers: IncomingHttpHeaders): void {
  console.log(headers["user-agent"]);
}

Kompilyator:

text
TS1484: 'IncomingHttpHeaders' is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled.

IncomingHttpHeaders — so'rov sarlavhalari obyektining turi (interface), kodda u faqat tur sifatida ishlatildi. tsc butun dasturni ko'radi va buni biladi. Transpiler esa faqat shu faylni ko'radi: node:http dan kelgan narsa tur yoki qiymat ekanini aniqlay olmaydi. Uni o'chirsa — qiymat bo'lsa kod buziladi. Qoldirsa — tur bo'lsa, ishlash paytida bunday eksport yo'q.

Tarjimasi: "IncomingHttpHeaders — tur, verbatimModuleSyntax yoqilganda u faqat tur importi bilan import qilinishi kerak". Tuzatish — Modullar TypeScript'da darsidagi import type:

ts
// @ts-options: {"verbatimModuleSyntax": true}
import type { IncomingHttpHeaders } from "node:http";

function logAgent(headers: IncomingHttpHeaders): void {
  console.log(headers["user-agent"]);
}
logAgent({ "user-agent": "Chrome" }); // Chrome

Endi har qanday transpiler biladi: import type qatori to'liq o'chiriladi. verbatimModuleSyntax — "importni yozilganidek qoldir" degan qoida, u fayl-fayl o'girishni xavfsiz qiladi. Undan oldingi, yumshoqroq bayroq — isolatedModules. Uni eski loyihalarda ko'p uchratasiz: ma'nosi o'sha — "har fayl alohida o'girilsa ham to'g'ri ishlaydigan kod yoz".

vazifalar ning tsconfig.json ida verbatimModuleSyntax Obyekt turlari darsidagi qadamdan beri yoqiq. Node 24 testlari ham .ts ni fayl-fayl o'chiradi — ularga ham shu shart kerak edi.

3.4 Tuzoq: esbuild importni o'zgartirmadi

vazifalar ning 19 modulini esbuild bilan o'girib, asosiy.js ning boshiga qaradik:

js
import { VazifalarRoyxati, joriyTeg } from "./royxat.ts";

tsc esa xuddi shu qatorni "./royxat.js" qilib yozadi (rewriteRelativeImportExtensions). esbuild fayl-fayl o'girishda importdagi yo'lga tegmaydi. Brauzer royxat.ts ni so'raydi — dist/ da bunday fayl yo'q, sahifa ishlamaydi.

Bu esbuild'ning kamchiligi emas. Uni bunday ishlatish odatiy emas: esbuild ham, boshqa vositalar ham odatda bundler sifatida ishlaydi. Bundler (yig'uvchi) — ko'p modulni import zanjiri bo'yicha kuzatib, bitta yoki bir nechta faylga birlashtiradigan vosita. Unda "./royxat.ts" degan yo'l umuman qolmaydi — modul to'g'ridan-to'g'ri faylning ichiga kiradi. Bundler'lar — 16-qism mavzusi (Bundler nima). Bu qismda vazifalar tsc bilan qoladi.

Tekshirib ko'ring: esbuild tur xatosi bor faylni xatosiz o'girdi. Demak esbuild TypeScript'ni "tushunmaydi"mi?

Javob

Tushunadi — sintaksisini. : number, interface, import type qayerda ekanini biladi va o'chiradi. Lekin turlarni solishtirmaydi: string ni number kutgan joyga berish uning ishi emas. Buning uchun butun dastur, lib.dom.d.ts, kutubxona turlari kerak — bu tsc ning ishi. Shuning uchun transpiler bilan ishlaganda tsc --noEmit alohida yuritiladi.

4. Zamonaviy juftlik: tsc --noEmit + bundler

4.1 Kim nima qiladi

Frontend loyihaning tipik ish tartibi:

flowchart TB
  A["src/*.ts"] --> B["Vite / esbuild<br/>turlarni o'chiradi"]
  B --> C["dist/ — brauzerga"]
  A --> D["tsc --noEmit<br/>faqat tekshiradi"]
  D --> E["xato bo'lsa —<br/>CI qizil"]

Sxemaga qarang: ikki yo'l bir-biriga bog'liq emas. Chap yo'l sayt uchun faylni yasaydi, o'ng yo'l faqat "xato bormi?" deb javob beradi. Ikkalasi ham bitta manbadan o'qiydi.

package.json da bu odatda shunday ko'rinadi (Vite loyihasi):

json
  "scripts": {
    "dev": "vite",
    "tip": "tsc --noEmit",
    "build": "tsc --noEmit && vite build"
  }
  • dev — ishlab chiqish serveri. Faylni saqlaysiz — brauzer bir zumda yangilanadi. Tur xatosi uni to'xtatmaydi (xato VS Code'da qizil chiziq bo'lib turadi).
  • build — avval tekshiruv, keyin yig'ish. && — "birinchisi muvaffaqiyatli bo'lsa, ikkinchisini bajar". Tur xatosi bo'lsa, sayt umuman yig'ilmaydi.

Vite — hozirgi frontend'ning eng mashhur yig'ish vositasi (16-qismda batafsil, Vite I). Vite 8 (2026-yil 12-mart) ichida Rolldown bundler'i va Oxc transpiler'i ishlaydi (ikkalasi Rust'da). Avvalgi versiyalarda bu ishni esbuild qilardi. Nomlar o'zgaradi — g'oya qoladi: tez vosita yozadi, tsc tekshiradi.

4.2 Eng katta tuzoq

vite build muvaffaqiyatli tugadi — bu turlar to'g'ri degani emas. Agar build skriptidan tsc --noEmit && qismini olib tashlasangiz, tur xatosi bilan sayt bemalol yig'iladi va chiqib ketadi. Tekshiruv faqat siz uni qayerdadir yuritsangizgina bor: build da, CI'da yoki ikkalasida.

4.3 vazifalar nega hali tsc bilan

vazifalar da bundler yo'q, 19 ta modul brauzerga alohida fayl bo'lib boradi. Bu holatda tsc eng sodda yo'l: u tekshiradi, yozadi va importlarni .js ga almashtiradi. 0,54 soniya — kutish emas. Bundler'ga o'tish uchun sabab paydo bo'lganda (masalan, Zod va turni sxemadan chiqarish darsidagi Zod kutubxonasi) — 16-qismda o'tamiz.

Tekshirib ko'ring: Jamoadoshingiz "build": "vite build" deb yozdi va "tez ishlayapti" dedi. Nima yetishmayapti?

Javob

Tur tekshiruvi. Vite turlarni faqat o'chiradi. tsc --noEmit hech qayerda yuritilmasa, tur xatosi bor kod saytga chiqadi. Yechim: "build": "tsc --noEmit && vite build" yoki CI'da alohida npm run tip qadami.

5. Tekshiruvni tezlashtirish

5.1 incremental — oldingi natijani eslab qolish

tsc har safar hamma narsani noldan tekshiradi. incremental bayrog'i bilan u natijani .tsbuildinfo fayliga yozib qo'yadi. Keyingi safar u faqat o'zgargan fayllarni qayta tekshiradi.

bash
npx tsc --noEmit --incremental --tsBuildInfoFile .tip.tsbuildinfo

vazifalar da ketma-ket to'rt marta: 591 ms (birinchi — fayl yo'q), keyin 305, 237, 200 ms. Ikkinchi ishga tushirishdan boshlab taxminan 2–3 baravar tez. .tsbuildinfo — kesh, uni har kim o'zida yasaydi. U .gitignore ga yoziladi.

5.2 Project references — loyihani bo'laklarga bo'lish

Katta loyiha (masalan, "frontend", "backend" va "umumiy turlar" bir repoda — monorepo) bitta tsconfig.json bilan sekin. Uni bir nechta kichik loyihaga bo'lish mumkin:

  • har bo'lakda o'z tsconfig.json, unda "composite": true;
  • boshqasiga tayanadigan bo'lak — "references": [{ "path": "../narx" }];
  • yig'ish — tsc -b (--build): bo'laklarni to'g'ri tartibda yig'adi va o'zgarmaganlarini o'tkazib yuboradi.

composite loyiha o'zi uchun .d.ts yozadi. Unga tayangan loyiha esa uning manbasini qayta tekshirmaydi — tayyor .d.ts ni o'qiydi. Bu Declaration fayllari darsidagi .d.ts ning yana bir ishi. Ikki bo'lakli kichik loyihani 3-mashqda o'zingiz yig'asiz.

Vite + React loyihasida tsconfig.app.json va tsconfig.node.json bo'linishi aynan shu mexanizm (tsconfig Vite + React loyihada, 16-qism).

5.3 isolatedDeclarations — .d.ts ni ham fayl-fayl yozish

.d.ts yozish uchun tsc odatda turlarni chiqaradi (tur chiqarish): return Math.round(…) dan natija number ekanini o'zi topadi. Bu tekshiruvchining ishi — sekin. isolatedDeclarations bayrog'i talab qiladi: eksport qilinadigan narsaning turi kodda yozilgan bo'lsin. Shunda .d.ts ni ham transpiler fayl-fayl, tekshiruvsiz yoza oladi:

ts
// @ts-options: {"isolatedDeclarations": true, "declaration": true}
export const SERVICE_RATE = 0.1;
export function withService(sum: number) {
  return Math.round(sum * (1 + SERVICE_RATE));
}
export const menu = ["Osh", "Manti"];

Kompilyator:

text
TS9013: Expression type can't be inferred with --isolatedDeclarations.
TS9017: Only const arrays can be inferred with --isolatedDeclarations.

Tarjimasi: birinchisi — "ifoda turini --isolatedDeclarations bilan chiqarib bo'lmaydi" (return dagi Math.round(…) belgilangan). Ikkinchisi — "faqat const massivlarning turi chiqariladi". SERVICE_RATE = 0.1 ga xato yo'q: oddiy literal qiymatning turi qiymatning o'zidan ko'rinadi. Tuzatish:

ts
// @ts-options: {"isolatedDeclarations": true, "declaration": true}
export const SERVICE_RATE = 0.1;
export function withService(sum: number): number {
  return Math.round(sum * (1 + SERVICE_RATE));
}
export const menu: string[] = ["Osh", "Manti"];
console.log(withService(80000), menu.length); // 88000 2

Bu bayroq hamma loyihaga kerak emas. U kutubxonalar va katta monorepolar uchun: .d.ts yasash tezlashadi. Bonus — eksportlar imzosi kodda ochiq turadi, tur annotatsiyasi darsidagi "export funksiyaga natija turini yozing" maslahati majburiy qoidaga aylanadi.

Tekshirib ko'ring: incremental va project references — ikkalasi ham "qayta tekshirmaslik" haqida. Farqi nimada?

Javob

incremental — bitta loyiha ichida: o'zgarmagan fayllarning oldingi natijasini .tsbuildinfo dan oladi. Project references — loyihani bo'laklarga bo'ladi: o'zgarmagan bo'lak umuman yig'ilmaydi, unga tayanganlar uning tayyor .d.ts ini o'qiydi. tsc -b ikkalasini birga ishlatadi — har bo'lakda .tsbuildinfo paydo bo'ladi.

6. TypeScript 7 va tsgo

6.1 Qisqa tarix

  • 2025-yil 11-mart — TypeScript jamoasi (Anders Hejlsberg) "A 10x faster TypeScript" e'lonini qildi: kompilyator JavaScript'dan Go tiliga ko'chiriladi.
  • 2025-yil may — sinov versiyasi npm'da: @typescript/native-preview paketi, buyruq nomi — tsgo. Ko'p jamoa uni tsc yonida sinab ko'rdi.
  • 2026-yil 23-mart — TypeScript 6.0: JavaScript'dagi oxirgi versiya, ko'prik.
  • 2026-yil 8-iyul — TypeScript 7.0: Go'dagi kompilyator endi oddiy typescript paketi, buyrug'i — oddiy tsc.

Demak "tsgo" — nom tarixi. typescript@7.0.2 o'rnatilgan loyihada npx tsgo buyrug'i yo'q: buyruq tsc. Maqolalarda "tsgo bilan tekshirdik" degan gapni ko'rsangiz — bu TS 7 ning sinov versiyasi.

6.2 Nima o'zgardi

Tezlik — O'rnatish darsidagi grafikda: Microsoft o'lchovida 8–12 baravar. Bizning vazifalar da 1,49 s → 0,54 s. Sabablari: Go — tayyor mashina kodi, va tekshiruv bir necha oqimda (parallel) ketadi. Buni boshqaradigan yangi bayroqlar:

Bayroq Ma'nosi
--checkers N bitta loyihani nechta oqim tekshiradi (standart — 4)
--builders N tsc -b da nechta loyiha bir vaqtda yig'iladi
--singleThreaded hammasi bitta oqimda

vazifalar da --checkers 1 bilan — 0,60 s (4 bilan — 0,54 s). Kichik loyihada parallel ishning foydasi oz, kattasida — sezilarli.

Eskirgan sozlamalar olib tashlandi. Eski loyihani TS 7 ga o'tkazganingizda shunday xabar ko'rishingiz mumkin (tsc 7.0.2, haqiqiy chiqish):

text
error TS5108: Option 'target=ES5' has been removed. Please remove it from your configuration.
error TS5108: Option 'moduleResolution=node10' has been removed. Please remove it from your configuration.
error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration.

Tarjimasi: "target=ES5 sozlamasi olib tashlangan. Uni sozlamangizdan o'chiring". E'londagi ro'yxat: target: es5, moduleResolution: node/node10/classic, module: amd/umd/system/none, baseUrl. Bular 6.0 da "eskirgan" deb ogohlantirilgan edi. Shuning uchun eski loyiha avval 6.0 ga o'tkaziladi, ogohlantirishlar tuzatiladi, keyin 7.0 ga.

6.3 Nega vazifalar da ikki TypeScript

TypeScript 7.0 da dasturiy API yo'q. API — boshqa dasturlar kompilyatordan JavaScript orqali foydalanishi uchun funksiyalar to'plami. Microsoft uni 7.1 da va'da qilgan. typescript-eslint (ESLint'ning TypeScript plagini) aynan shu API'ga tayanadi. Uning 8.71.1 versiyasi package.json da typescript: ">=4.8.4 <6.1.0" deb yozadi — 7 ni qabul qilmaydi.

Shuning uchun vazifalar da TS 7.0 e'lonidagi rasmiy yo'l — ikki taxallus (alias):

json
    "@typescript/native": "npm:typescript@7.0.2",
    "typescript": "npm:@typescript/typescript6@6.0.2",
  • npx tsc → Version 7.0.2 — build va npm run tip.
  • npx tsc6 → Version 6.0.3 — faqat ESLint ichida. (Raqamlar farqiga hayron bo'lmang: @typescript/typescript6 o'ram paketining versiyasi — 6.0.2, ichidagi TypeScript esa — 6.0.3.)

@typescript/native — npm'dagi paket nomi emas, faqat package.json dagi taxallus: npm:typescript@7.0.2 ni shu nom ostida o'rnat. Hozir (2026-yil oktabr) holat shunday. 7.1 chiqib, typescript-eslint unga o'tgach, bitta paket qoladi.

7. Ko'p uchraydigan xatolar

7.1 "Build o'tdi — demak turlar to'g'ri"

Transpiler (esbuild, SWC, Vite) bilan yig'ilgan loyihada bu noto'g'ri. Tekshiruv — faqat tsc --noEmit. U build skriptida yoki CI'da bo'lishi shart.

7.2 TS1484 — tur oddiy import bilan

verbatimModuleSyntax yoqiq, turni import { … } bilan oldingiz. Tuzatish: import type { … } yoki aralash importda import { type User, getUser }.

7.3 TS5108 / TS5102 — TS 7 ga o'tgach

Eski tsconfig.json da olib tashlangan sozlama qolgan. Tuzatish: xabardagi sozlamani o'chiring yoki zamonaviysiga almashtiring (target: "es2024", moduleResolution: "bundler" yoki "nodenext"). baseUrl siz yo'l taxalluslari — paths (16-qismda, Path alias).

7.4 .tsbuildinfo git'da

incremental yoki tsc -b dan keyin paydo bo'ladigan fayl commit qilinsa, jamoadoshning tsc si eskirgan keshni o'qib, g'alati xulq ko'rsatishi mumkin. Tuzatish: *.tsbuildinfo — .gitignore ga.

7.5 npx tsgo — "command not found"

tsgo faqat @typescript/native-preview sinov paketida bor. Tuzatish: TypeScript 7 da buyruq — npx tsc, versiyani npx tsc --version bilan tekshiring.

8. Mashqlar

1-mashq (oson): Kim nimani ko'radi

«esbuild bilan sinab ko'ramiz» bo'limidagi tip.ts ni eslang. Bo'sh joylarni to'ldiring:

  • npx tsc --noEmit tip.ts — chiqish kodi .
  • npx esbuild tip.ts --outfile=tip.js — chiqish kodi .
  • node tip.js ekranga chiqaradi: .
Yechim

tsc tur xatosini ko'radi — TS2345, chiqish kodi 1 (--noEmit bilan: xato bor, hech narsa yozilmadi). esbuild turlarni tekshirmaydi — 0. node tip.js — 800008000: 80000 + "8000" satrlarni yopishtirdi. Xulosa: transpiler bilan ishlasangiz, tsc --noEmit alohida qadam bo'lishi shart.

2-mashq (o'rta): incremental bilan npm run tip

kurs/mashqlar/15/ dagi umumiy loyihada tekshiruvni tezlashtiring.

  1. package.json ga skript qo'shing: "tip": "tsc --incremental --tsBuildInfoFile .tip.tsbuildinfo". (noEmit tsconfig.json da allaqachon bor.)
  2. npm run tip ni ketma-ket uch marta ishga tushiring. Vaqtni o'lchash uchun Git Bash'da buyruq oldiga time yozing: time npm run tip.
  3. Papkada qanday yangi fayl paydo bo'ldi? Uni git'ga qo'shish kerakmi?
Yechim
json
  "scripts": {
    "tip": "tsc --incremental --tsBuildInfoFile .tip.tsbuildinfo"
  }

Birinchi ishga tushirishda tsc hammasini tekshiradi va .tip.tsbuildinfo faylini yozadi. Keyingilarida o'zgarmagan fayllarni qayta tekshirmaydi — vazifalar da 591 ms → 200–300 ms bo'lgan edi. Sizning raqamlaringiz boshqacha bo'ladi (kompyuter, fayllar soni), lekin ikkinchi ishga tushirish sezilarli tezroq.

.tip.tsbuildinfo — JSON ko'rinishidagi kesh: fayllar ro'yxati, ularning "barmoq izi" (hash) va topilgan xatolar. Uni git'ga qo'shmaymiz — kurs repo'sining .gitignore iga:

text
*.tsbuildinfo

3-mashq (qiyin): Amaliy tajriba — ikki bo'lakli loyiha

kurs/mashqlar/15/38-build/ da project references bilan ikki bo'lakli loyiha quring. Bu — alohida build loyihasi (xuddi 02-ornatish/ kabi), shuning uchun avval ildizdagi tsconfig.json ning exclude iga "38-build" ni qo'shing.

  • narx/ — kutubxona bo'lagi: src/narx.ts da SERVICE_RATE = 0.1 va withService(sum) (summa + 10%, Math.round). tsconfig.json da composite va isolatedDeclarations.
  • kassa/ — dastur bo'lagi: src/index.ts narx dan withService ni oladi va Xizmat haqi bilan: 88000 so'm chiqaradi (35000 * 2 + 5000 * 2 uchun).
  • 38-build/ dan: npx tsc -b kassa --verbose, keyin node kassa/dist/index.js. Keyin tsc -b ni yana bir marta yuriting va --verbose nima deyishini o'qing.

Ishora: kassa narx ning natijasini import qiladi: "../../narx/dist/narx.js". Turlarni tsc yonidagi narx.d.ts dan oladi.

Yechim

narx/tsconfig.json:

json
{
  "compilerOptions": {
    "composite": true,
    "isolatedDeclarations": true,
    "strict": true,
    "target": "es2024",
    "module": "nodenext",
    "rootDir": "src",
    "outDir": "dist"
  }
}

narx/src/narx.ts:

ts
// «Bahor» narxlari: xizmat haqi bilan hisoblash
export const SERVICE_RATE = 0.1;

export function withService(sum: number): number {
  return Math.round(sum * (1 + SERVICE_RATE));
}

kassa/tsconfig.json — composite shart emas (unga hech kim tayanmaydi), lekin references bor:

json
{
  "compilerOptions": {
    "strict": true,
    "target": "es2024",
    "module": "nodenext",
    "rootDir": "src",
    "outDir": "dist"
  },
  "references": [{ "path": "../narx" }]
}

kassa/src/index.ts:

ts
import { withService } from "../../narx/dist/narx.js";

const total = 35000 * 2 + 5000 * 2;
console.log(`Xizmat haqi bilan: ${withService(total)} so'm`);

npx tsc -b kassa --verbose (vaqtlarsiz):

text
Projects in this build:
    * narx/tsconfig.json
    * kassa/tsconfig.json

Project 'narx/tsconfig.json' is out of date because output file 'narx/tsconfig.tsbuildinfo' does not exist
Building project 'narx/tsconfig.json'...
Project 'kassa/tsconfig.json' is out of date because output file 'kassa/tsconfig.tsbuildinfo' does not exist
Building project 'kassa/tsconfig.json'...

tsc -b avval narx ni yig'di (unga kassa tayanadi), keyin kassa ni. node kassa/dist/index.js — Xizmat haqi bilan: 88000 so'm. narx/dist/narx.d.ts:

ts
export declare const SERVICE_RATE = 0.1;
export declare function withService(sum: number): number;

Ikkinchi tsc -b kassa --verbose — ikkala bo'lak uchun is up to date because newest input … is older than output … ("eng yangi manba natijadan eskiroq — yangilanmagan"): hech narsa qayta yig'ilmadi.

Tajriba uchun ikki xatoni ham ko'rdik. withService dan : number olib tashlab, toza papkada (dist/ va .tsbuildinfo siz) npx tsc -b kassa --pretty false (yo'l qisqartirildi):

text
narx/src/narx.ts(5,10): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
kassa/src/index.ts(1,29): error TS7016: Could not find a declaration file for module '../../narx/dist/narx.js'. '…/38-build/narx/dist/narx.js' implicitly has an 'any' type.

TypeScript aytyapti: birinchisi — "--isolatedDeclarations bilan ifoda turini chiqarib bo'lmaydi"; ikkinchisi — "narx.js uchun e'lon fayli topilmadi". Ikkinchi xato birinchisining oqibati: narx da xato bo'lgani uchun narx.d.ts yozilmadi, kassa esa turlarni aynan shu fayldan oladi. Qoida: zanjirdagi birinchi xatoni tuzating — qolganlari ko'pincha o'zi yo'qoladi.

narx da composite o'rniga faqat declaration bo'lsa (yo'l qisqartirildi):

text
kassa/tsconfig.json(9,18): error TS6306: Referenced project '…/38-build/narx' must have setting "composite": true.

Tarjimasi: "havola qilingan loyihada composite: true bo'lishi shart". XATOLAR.md ga bu darsning yangi xabarlarini qo'shing: TS1484, TS9013, TS9017, TS5108, TS5102, TS6306. *.tsbuildinfo va dist/ ni .gitignore ga yozib, kurs/mashqlar papkasidan:

bash
git add 15/38-build 15/tsconfig.json 15/package.json 15/XATOLAR.md
git commit -m "15/38: project references — narx va kassa, tsc -b"

9. Real ishda

  • Deyarli har frontend loyihada (React, Vue, Svelte — 17-qismdan) JavaScript'ni Vite yoki boshqa bundler yozadi, tsc --noEmit esa typecheck yoki tip skripti bo'lib CI'da turadi. Ishga kirganingizda package.json dagi shu ikki skriptni toping.
  • Node backend'larda (24-qismdan) ikki yo'l uchraydi: tsc bilan dist/ ga yig'ish yoki Node'ning type stripping'i bilan to'g'ridan-to'g'ri node src/index.ts. Ikkalasida ham tekshiruv — tsc --noEmit.
  • Monorepo'lar (Turborepo, Nx kabi vositalar bilan — IlmHamroh platformasi ham shunday tuzilgan) project references va incremental ga tayanadi.
  • TS 7 ga ko'chish — 2026-yilning eng ko'p uchraydigan vazifalaridan biri: olib tashlangan sozlamalarni tozalash, CI'da tezlikni o'lchash, typescript-eslint uchun TS 6 ni yonida saqlash.
  • Intervyu: "Vite turlarni tekshiradimi?", "isolatedModules nega kerak?", "tsc -b nima qiladi?".

Xulosa

  • tsc ikki ish qiladi: tekshiradi (sekin qism) va JavaScript yozadi (tez qism). vazifalar da --noEmit va emit deyarli bir xil vaqt — 0,54 s.
  • Transpiler (esbuild, SWC, Oxc) turlarni faqat o'chiradi, tekshirmaydi: tur xatosi bor fayl jim o'giriladi.
  • Fayl-fayl o'girish uchun verbatimModuleSyntax (yoki isolatedModules): tur — import type bilan.
  • Zamonaviy juftlik: bundler yig'adi, tsc --noEmit tekshiradi — build da yoki CI'da, albatta.
  • Tezlashtirish: incremental (.tsbuildinfo), project references (composite, references, tsc -b), isolatedDeclarations.
  • TypeScript 7 — Go'dagi tsc (sinov nomi tsgo): tezroq, parallel, eski sozlamalar olib tashlangan; API 7.1 da — hozircha ESLint uchun TS 6 yonida turadi.

Keyingi dars: Standart dekoratorlar (TC39) — @ belgisi bilan klass metodlariga qo'shimcha xulq qo'shamiz va dekoratorlar nega "o'chirib bo'lmaydigan" sintaksis ekanini tsc chiqishida ko'ramiz.

Manbalar

  • TypeScript blogi: "A 10x Faster TypeScript" (2025-03-11), "Announcing TypeScript 7.0" (2026-07-08) — devblogs.microsoft.com/typescript
  • TypeScript hujjatlari: "Project References", TSConfig incremental, isolatedModules, verbatimModuleSyntax, isolatedDeclarations — typescriptlang.org
  • esbuild hujjatlari: "Content Types → TypeScript caveats" — esbuild.github.io
  • Vite 8 e'loni (2026-03-12) — vite.dev/blog
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
TypeScript build: tsc, bundler'lar va tsgo — tekshirish va JavaScript yozishni ajratish — IlmHamroh