IlmHamroh
JavaScript Full-stack/15-qism. TypeScript2/47-dars24 daqiqa
Mundarija (36)

TypeScript'ni o'rnatish va ishga tushirish: tsc, tsconfig.json va Node 24

Qisqacha: TypeScript loyihaga npm install --save-dev typescript bilan o'rnatiladi va npx tsc buyrug'i bilan ishlaydi. npx tsc --init sozlama fayli — tsconfig.json ni yaratadi. npx tsc kodni tekshirib, .js fayllarni yozadi; npx tsc --noEmit faqat tekshiradi. Node 24 esa .ts faylni to'g'ridan-to'g'ri ishga tushira oladi (node index.ts), lekin turlarni tekshirmaydi — faqat o'chirib tashlaydi.

Bu darsda

  • TypeScript 7.0.2 ni loyihaga o'rnatasiz va npx tsc bilan versiyasini tekshirasiz.
  • npx tsc --init bilan tsconfig.json yaratasiz va undagi asosiy qatorlarni tushunasiz.
  • .ts faylni tsc bilan JavaScript'ga aylantirasiz va natijani Node'da ishga tushirasiz.
  • tsc, tsc --noEmit, node fayl.ts va tsx farqini — kim tekshiradi, kim bajaradi — ayta olasiz.
  • TS Playground'da kodni o'rnatishsiz sinaysiz.

Oldin bilishingiz kerak: Nega TypeScript, npm'ga birinchi qadam, JSDoc va // @ts-check, Birinchi avtomatik test.

1. Nega bu kerak?

Oldingi darsda TypeScript «Bahor» kassasidagi ikki xatoni kod ishga tushmasdan topdi. Lekin biz kodni faqat saytdagi bloklarda va Playground'da ko'rdik. Endi uni o'z kompyuteringizda ishlatamiz.

Bitta muammo bor: brauzer ham, Node ham asli JavaScript'ni bajaradi. .ts faylni ishga tushirishning uch yo'li bor:

flowchart TB
  A["index.ts"] --> B["npx tsc<br/>tekshiradi + .js yozadi"]
  B --> C["dist/index.js"]
  C --> D["node yoki brauzer"]
  A --> E["node index.ts<br/>turlarni o'chirib bajaradi"]
  A --> F["TS Playground<br/>brauzerda sinash"]

Sxemaga qarang: faqat chap yo'l — tsc — turlarni tekshiradi. O'rtadagi node index.ts tez, lekin tekshirmaydi. Bugun uchalasini ham sinaymiz va qaysi biri qachon kerakligini aniqlaymiz.

Hayotiy o'xshatish: tsc — oshxonadagi tekshiruvchi oshpaz. U har taomni tatib ko'radi va keyin mijozga chiqaradi. node index.ts esa ofitsiant: taomni darhol olib chiqadi, lekin tatib ko'rmaydi. Ikkalasi ham kerak — faqat bir-birining ishini qilmaydi.

2. TypeScript'ni o'rnatish

2.1 Loyiha papkasi

kurs/mashqlar/15/02-ornatish/ papkasini yarating va terminalda shu papkaga kiring. Avval package.json (npm'ga birinchi qadam):

bash
npm init -y
npm pkg set type=module
  • npm init -y — standart package.json yaratadi.
  • npm pkg set type=module — package.json ga "type": "module" yozadi. npm 11 npm init -y da "type": "commonjs" qo'yadi. Biz esa 10-qismdan beri ES modullar bilan ishlaymiz — import/export.

2.2 typescript paketi

bash
npm install --save-dev --save-exact typescript@7.0.2

Bu buyruqni JSDoc va // @ts-check darsida vazifalar uchun ham bergan edingiz. Bayroqlarni eslaymiz:

  • --save-dev (qisqasi -D) — paket faqat dasturchiga kerak. Foydalanuvchining brauzeriga TypeScript yetib bormaydi: unga tayyor .js boradi.
  • --save-exact — package.json ga aniq 7.0.2 yoziladi, ^7.0.2 emas. Jamoadagi hamma bir xil kompilyator bilan ishlaydi.

Natija:

text
added 2 packages, and audited 3 packages in 2s

found 0 vulnerabilities

Ikki paket? Biri — typescript, ikkinchisi — @typescript/typescript-win32-x64 (Windows uchun; Mac yoki Linux'da nomi boshqa). Ikkinchisining ichida tsc.exe turibdi — 24,5 MB lik tayyor dastur. TypeScript 7 kompilyatori Go tilida yozilgan va har operatsion tizim uchun alohida yig'ilgan. npm sizning tizimingizga mosini o'zi tanlaydi.

2.3 npx tsc --version

bash
npx tsc --version
text
Version 7.0.2

npx — "shu loyihaning node_modules idagi buyruqni ishga tushir". Shuning uchun tsc ni kompyuterga global o'rnatish shart emas: har loyiha o'z versiyasini ishlatadi. Bir loyiha TypeScript 6 da, boshqasi 7 da bo'lishi mumkin — ular to'qnashmaydi.

Diqqat: npx tsc ni typescript o'rnatilmagan papkada yozsangiz, npm internetdan boshqa paketni yuklaydi — 2.0.4 versiyali eskirgan tsc paketini. U faqat ogohlantirish chiqaradi: This is not the tsc command you are looking for. Avval npm install, keyin npx tsc.

2.4 TypeScript 7 haqida bir necha fakt

  • TypeScript 7.0 2026-yil 8-iyulda chiqdi. Kompilyator JavaScript'dan Go tiliga qayta yozildi. Sinov versiyalarida u tsgo deb atalardi (@typescript/native-preview paketi), 7.0 da oddiy tsc bo'ldi.
  • TypeScript 6.0 (2026-yil 23-mart) — JavaScript'da yozilgan oxirgi versiya, 5.9 dan 7.0 ga ko'prik. strict ni standart holda yoqish kabi o'zgarishlar shu versiyada boshlangan.
  • Tezlik farqi katta. Microsoft o'lchovida to'liq tekshiruv 8–12 baravar tezlashgan:
To'liq build vaqti: TypeScript 6.0 va 7.0
  • VS Code, TS 6125,7 s
  • VS Code, TS 711,9 baravar tez10,6 s
  • Sentry, TS 6139,8 s
  • Sentry, TS 78,9 baravar tez15,7 s

Manba: Microsoft, «Announcing TypeScript 7.0», 2026-07-08 — devblogs.microsoft.com/typescript/announcing-typescript-7-0/

Grafikdagi loyihalar — juda katta kod bazalari. Kichik vazifalar da tsc --noEmit ni biz ham o'lchadik: TypeScript 7 — taxminan 0,4 s, TypeScript 6.0.3 — taxminan 1,2 s. Kichikda farq soniya ulushlarida, kattada — daqiqalarda.

Tekshirib ko'ring: Nega TypeScript --save-dev bilan o'rnatiladi, oddiy dependency sifatida emas?

Javob

TypeScript faqat dasturchining kompyuterida ishlaydi: kodni tekshiradi va .js yozadi. Saytga chiqadigan narsa — tayyor .js. Foydalanuvchi brauzeriga kompilyator kerak emas, shuning uchun u "dasturchi asbobi" (devDependency).

3. tsconfig.json: tsc --init

3.1 Sozlama faylini yaratish

12/39 da sozlama jsconfig.json da edi. TypeScript loyihasida uning nomi — tsconfig.json. Uni qo'lda yozish shart emas:

bash
npx tsc --init
text
Created a new tsconfig.json

You can learn more at https://aka.ms/tsconfig

Yaratilgan fayl (TypeScript 7.0.2):

json
{
  // Visit https://aka.ms/tsconfig to read more about this file
  "compilerOptions": {
    // File Layout
    // "rootDir": "./src",
    // "outDir": "./dist",

    // Environment Settings
    // See also https://aka.ms/tsconfig/module
    "module": "nodenext",
    "target": "esnext",
    "types": [],
    // For nodejs:
    // "lib": ["esnext"],
    // "types": ["node"],
    // and npm install -D @types/node

    // Other Outputs
    "sourceMap": true,
    "declaration": true,
    "declarationMap": true,

    // Stricter Typechecking Options
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,

    // Style Options
    // "noImplicitReturns": true,
    // "noImplicitOverride": true,
    // "noUnusedLocals": true,
    // "noUnusedParameters": true,
    // "noFallthroughCasesInSwitch": true,
    // "noPropertyAccessFromIndexSignature": true,

    // Recommended Options
    "strict": true,
    "jsx": "react-jsx",
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "noUncheckedSideEffectImports": true,
    "moduleDetection": "force",
    "skipLibCheck": true,
  }
}

Bugun hammasini bilish shart emas. Bu oddiy JSON emas: unda // izohlar va oxirgi vergul bor. TypeScript bunga ruxsat beradi (oddiy JSON.parse esa xato berardi).

3.2 Hozir bilish kerak bo'lgan qatorlar

Qator Ma'nosi
rootDir, outDir manba qayerda, .js qayerga yoziladi
module, target qaysi modul tizimi va JavaScript versiyasi
strict: true qat'iy rejim — 12/39 dagi kabi
sourceMap, declaration… qo'shimcha fayllar (pastda ko'ramiz)

Qolganlari — keyingi darslar uchun: noUncheckedIndexedAccess va boshqa qat'iy bayroqlar — Strict bayroqlar oilasi, verbatimModuleSyntax — Modullar TypeScript'da, jsx — React (17-qism, hozir bilish shart emas). Butun faylni tsconfig.json chuqur darsida qatorma-qator o'qiymiz.

Endi bitta o'zgarish qilamiz: "File Layout" ostidagi ikki qatorning boshidagi // ni o'chiring:

json
    "rootDir": "./src",
    "outDir": "./dist",

Endi manba kod src/ papkasida, tsc natijasi dist/ papkasiga tushadi. dist — "distribution", ya'ni "tarqatiladigan" nusxa.

Tekshirib ko'ring: Hozir npx tsc ni ishga tushirsak, nima bo'ladi? (src/ hali bo'sh.)

Javob

Xato chiqadi — tekshiradigan fayl yo'q:

text
error TS18003: No inputs were found in config file '…/02-ornatish/tsconfig.json'. Specified 'include' paths were '["**/*"]' and 'exclude' paths were '["…/02-ornatish/dist"]'.

Tarjimasi: "Sozlama faylida kirish fayllari topilmadi. include yo'llari — **/* (hamma papka, hamma fayl), exclude — dist papkasi". tsc o'z natijasi tushadigan dist/ ni o'zi chetlab o'tadi. Ya'ni loyihada birorta .ts fayl yo'q. Yo'l o'rnida sizda papkangizning to'liq manzili turadi.

4. Birinchi kompilyatsiya

4.1 src/index.ts

src/index.ts faylini yarating. Oldingi darsdagi addTip ni olamiz:

ts
// «Bahor» kassasi: buyurtma summasi va choy puli
function addTip(total: number, tip: number): number {
  return total + tip;
}

const total = 35000 * 2 + 5000 * 2;
console.log(`Jami: ${total} so'm`);
console.log(`Choy puli bilan: ${addTip(total, 8000)} so'm`);

VS Code .ts faylni ochishingiz bilan uni tekshira boshlaydi. Hech narsa o'rnatmasdan ham noto'g'ri tur ostida qizil chiziq ko'rinadi — xuddi 12/39 dagi // @ts-check kabi.

4.2 npx tsc

bash
npx tsc

Hech narsa chiqmadi — bu yaxshi belgi. tsc xato topmasa, jim turadi. dist/ papkasiga qarang:

text
dist/
  index.d.ts
  index.d.ts.map
  index.js
  index.js.map

To'rtta fayl, lekin bizga hozir bittasi kerak:

Fayl Nima Kimga kerak
index.js tayyor JavaScript Node va brauzer
index.js.map .js qatorini .ts qatoriga bog'laydi DevTools va debugger
index.d.ts faqat turlar, kodsiz kodingizni ishlatadigan boshqa dastur
index.d.ts.map .d.ts ni .ts ga bog'laydi muharrir

.d.ts fayllarni Declaration fayllari darsida o'rganamiz. Ular keraksiz bo'lsa, tsconfig.json da "declaration": false va "declarationMap": false qilsangiz yetadi.

4.3 Natijani o'qiymiz va ishga tushiramiz

dist/index.js:

js
// «Bahor» kassasi: buyurtma summasi va choy puli
function addTip(total, tip) {
    return total + tip;
}
const total = 35000 * 2 + 5000 * 2;
console.log(`Jami: ${total} so'm`);
console.log(`Choy puli bilan: ${addTip(total, 8000)} so'm`);
export {};
//# sourceMappingURL=index.js.map

Turlar o'chdi — oldingi darsdagi type erasure. Oxirida ikki yangi qator:

  • export {}; — tsconfig.json dagi "moduleDetection": "force" har faylni modul deb hisoblaydi. Bo'sh export faylni modul qilib belgilaydi. Zarari yo'q.
  • //# sourceMappingURL=… — .js.map faylga ishora. DevTools xatoni .ts dagi qatorda ko'rsatishi uchun.

Ishga tushiramiz:

bash
node dist/index.js
text
Jami: 80000 so'm
Choy puli bilan: 88000 so'm

Ishladi. dist/ dagi faylni qo'lda tahrirlamang: keyingi npx tsc uni qayta yozib yuboradi.

5. Xato bo'lganda: tsc va tsc --noEmit

5.1 Kompilyator xabari terminalda

Oldingi darsdagi xatoni qaytaramiz. src/index.ts da choy puli formadan satr bo'lib keladi:

ts
// «Bahor» kassasi: buyurtma summasi va choy puli
function addTip(total: number, tip: number): number {
  return total + tip;
}

const total = 35000 * 2 + 5000 * 2;
const tip = "8000"; // formadan keldi — satr
console.log(`Jami: ${total} so'm`);
console.log(`Choy puli bilan: ${addTip(total, tip)} so'm`);

Xato:

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

Terminalda npx tsc buni batafsilroq ko'rsatadi:

text
src/index.ts:9:47 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

9 console.log(`Choy puli bilan: ${addTip(total, tip)} so'm`);
                                                ~~~


Found 1 error in src/index.ts:9

O'qilishi:

  • src/index.ts:9:47 — fayl, 9-qator, 47-ustun. VS Code terminalida bu yozuvni Ctrl bilan bossangiz, fayl shu joyda ochiladi.
  • error TS2345: … — xato kodi va xabar. Tarjimasi oldingi darsdan tanish: "satrni son kutilgan parametrga berib bo'lmaydi".
  • Pastda — qatorning o'zi, ~~~ bilan aynan tip belgilangan.
  • Found 1 error — jami 1 ta xato.

Terminalda rang ham bo'ladi: fayl nomi — moviy, error — qizil. 12/39 dagi price.js(14,24): … shakli esa — tsc chiqishi terminalga emas, faylga yoki boshqa dasturga ketganda (masalan CI'da).

5.2 Tuzoq: xato bo'lsa ham .js yozildi

Endi dist/ ga qarang — index.js yangilangan! Ishga tushiramiz:

text
Jami: 80000 so'm
Choy puli bilan: 800008000 so'm

Ha, tsc xatoni ko'rsatdi, lekin JavaScript'ni baribir yozdi. Bu standart xulq: TypeScript "xato bor, lekin mana sizga kod — o'zingiz hal qiling" deydi. Chiqish kodi esa 2 — "xato bor, fayllar yozildi".

Xato bo'lganda hech narsa yozilmasligi uchun tsconfig.json ga bitta bayroq qo'shiladi:

json
    "noEmitOnError": true,

Endi xato bo'lsa dist/ ga tegilmaydi va chiqish kodi 1 bo'ladi. Buni 2-mashqda o'zingiz tekshirasiz.

5.3 Faqat tekshirish: tsc --noEmit

Ba'zan fayl kerak emas — faqat "xato bormi?" degan javob kerak:

bash
npx tsc --noEmit

Chiqish o'sha xabar, lekin dist/ ga hech narsa yozilmaydi, chiqish kodi — 1. Bu buyruqni 12/39 dan bilasiz: vazifalar dagi npm run tip aynan shu. CI ham shuni ishlatadi: xato bor — chiqish kodi 0 emas — tekshiruv qizil.

Tekshirib ko'ring: npx tsc xato topdi va "Found 1 error" dedi. dist/index.js eski holatda qoldimi?

Javob

Yo'q, yangilandi. Standart holda tsc xato bo'lsa ham JavaScript yozadi — xatoli kod ham dist/ ga tushadi. Bunga yo'l qo'ymaslik uchun "noEmitOnError": true, faqat tekshirish uchun esa npx tsc --noEmit.

6. Node 24: node index.ts

6.1 To'g'ridan-to'g'ri ishga tushirish

Node 24 .ts faylni o'zi o'qiy oladi:

bash
node src/index.ts
text
Jami: 80000 so'm
Choy puli bilan: 800008000 so'm

Ishladi — va xato natijani jim chiqardi! Chiqish kodi 0, hech qanday ogohlantirish yo'q.

Node turlarni tekshirmaydi. U ularni bo'sh joy bilan almashtirib (o'chirib) tashlaydi va qolgan JavaScript'ni bajaradi. Bu type stripping ("turlarni sidirib tashlash") deyiladi. Turlar bo'sh joyga aylangani uchun qator va ustun raqamlari o'zgarmaydi: xato bo'lsa, Node sizning .ts faylingizdagi aniq qatorni ko'rsatadi.

Bu imkoniyat tarixi (nodejs.org hujjatidan):

Node Nima o'zgardi
22.6.0 type stripping qo'shildi (bayroq bilan)
23.6.0 standart holda yoqildi
24.3.0 "experimental" ogohlantirishi olib tashlandi
24.12.0 barqaror (stable) deb e'lon qilindi

Biz Node 24.21.0 da ishlaymiz — hech qanday bayroq kerak emas.

6.2 Node nimani bajarmaydi

Node faqat "o'chirib tashlash mumkin" bo'lgan sintaksisni tushunadi. TypeScript'da esa JavaScript'ga kod qo'shadigan bir nechta imkoniyat bor. Eng mashhuri — enum:

ts
enum OrderStatus {
  New,
  Ready,
}
console.log(OrderStatus.Ready); // 1

tsc bu kodni xatosiz qabul qiladi. Uni src/status.ts ga yozib, node src/status.ts bilan ishga tushirsak, Node 24 to'xtaydi:

text
SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode

Tarjimasi: "TypeScript enum i faqat-o'chirish rejimida qo'llab-quvvatlanmaydi". enum ni o'chirib tashlab bo'lmaydi — undan JavaScript obyekti yasash kerak. enum nima va nega vazifalar da u ishlatilmasligini enum va uning muqobillari darsida ko'ramiz. TypeScript'da shunday kodni oldindan taqiqlaydigan bayroq ham bor — erasableSyntaxOnly.

Yana ikki farq:

  • Node tsconfig.json ni o'qimaydi. Unga sozlama ta'sir qilmaydi.
  • Boshqa .ts faylni import qilganda kengaytma aniq yoziladi: import { addTip } from "./tip.ts". Bu haqda 3-mashqda.

6.3 tsx

Node'da type stripping paydo bo'lishidan oldin .ts ni bajarish uchun boshqa vositalar ishlatilgan. Eng mashhuri — tsx:

bash
npx tsx@4.23.15 src/index.ts

Birinchi marta npx paketni yuklashga ruxsat so'raydi — y ni bosing. tsx ham turlarni tekshirmaydi, lekin enum ni ham bajaradi va tsconfig.json dagi ba'zi sozlamalarni o'qiydi. Eski loyihalarda tsx yoki ts-node ni ko'p uchratasiz. Yangi loyihada Node 24 ning o'zi ko'pincha yetarli.

Tekshirib ko'ring: node src/index.ts "800008000" chiqardi va xato bermadi. Demak, Node'da TypeScript ishlamaydimi?

Javob

Node TypeScript sintaksisini tushunadi, lekin turlarni tekshirmaydi — faqat o'chiradi. Tekshiruv — tsc ning ishi (npx tsc --noEmit). Shuning uchun real loyihada ikkalasi birga: kod Node bilan ishga tushadi, turlar esa alohida tsc bilan tekshiriladi.

7. TS Playground

O'rnatishsiz sinash uchun — TypeScript Playground: typescriptlang.org/play. Bu TypeScript jamoasining rasmiy onlayn muharriri:

  • chapda — .ts kod, xato ostida qizil chiziq;
  • o'ngda — .JS yorlig'ida tsc chiqargan JavaScript, Errors yorlig'ida xatolar ro'yxati;
  • "TS Config" menyusida strict kabi bayroqlarni yoqib-o'chirish mumkin;
  • kodni havola qilib yuborish mumkin — havolada kodning o'zi saqlanadi.

Saytimizda har ```ts blok ostidagi «TS Playground'da ochish» havolasi kodni aynan shu yerda ochadi. Blok ostidagi «Ishga tushir» tugmasi esa Node kabi ishlaydi: turlarni o'chiradi va bajaradi, tekshirmaydi. Xatoni ko'rish uchun — Playground.

8. Qaysi biri qachon

TypeScript bilan ishlashda ikki alohida ish bor: tekshirish va bajarish. Vositalar shu ikki ishni turlicha bo'lib oladi:

Buyruq Tekshiradimi .js yozadimi
npx tsc ha ha (outDir)
npx tsc --noEmit ha yo'q
node fayl.ts yo'q yo'q, darhol bajaradi
npx tsx fayl.ts yo'q yo'q, darhol bajaradi

Kundalik ish tartibi:

  1. Yozish paytida — VS Code qizil chiziqlari.
  2. Tez sinash va testlar — node fayl.ts, node --test.
  3. Commit va CI'dan oldin — npx tsc --noEmit (npm run tip).
  4. Saytga chiqarish — npx tsc → dist/.

Katta frontend loyihalarda .js ni ko'pincha tsc emas, tezroq vositalar (esbuild, Vite) yozadi, tsc esa faqat tekshiradi. Bu bo'linishni Build: tsc, bundler'lar va tsgo darsida ko'ramiz.

9. Ko'p uchraydigan xatolar

9.1 TS18003: No inputs were found

tsconfig.json bor, lekin .ts fayl yo'q (yoki u include dan tashqarida). Tuzatish: fayl src/ ichida va kengaytmasi .ts ekanini tekshiring.

9.2 "Node ishga tushirdi — demak, turlar to'g'ri"

Yo'q. node fayl.ts turlarni tekshirmaydi — «Node 24» bo'limidagi "800008000" shuni ko'rsatdi. Tekshiruv — faqat tsc.

9.3 dist/ ni git'ga qo'shish

dist/ — tsc yasagan nusxa, uni har kim o'zida yasaydi. Git'da manba (src/) saqlanadi, dist/ esa .gitignore ga yoziladi — xuddi node_modules/ kabi.

10. Mashqlar

1-mashq (oson): O'z kompyuteringizda

Darsdagi qadamlarni kurs/mashqlar/15/02-ornatish/ da takrorlang: npm init -y, type=module, TypeScript 7.0.2, tsc --init, rootDir/outDir, src/index.ts, npx tsc, node dist/index.js. Keyin javob bering: src/index.ts dagi addTip(total, 8000) ni addTip(total) ga o'zgartirsangiz, tsc nima deydi?

Yechim
ts
function addTip(total: number, tip: number): number {
  return total + tip;
}

console.log(addTip(80000));

Xato:

text
TS2554: Expected 2 arguments, but got 1.

Tarjimasi: "2 ta argument kutilgan edi, lekin 1 ta berildi". JavaScript'da bu xatosiz NaN berardi: tip — undefined. Yangi xabarni kurs/mashqlar/15/XATOLAR.md ga qo'shing.

2-mashq (o'rta): Chiqish kodlari

src/index.ts ga choy puli satr bo'lgan versiyani qo'ying (const tip = "8000"). Har buyruqdan keyin echo $? bilan chiqish kodini ko'ring va bo'sh joylarni to'ldiring.

  • Oddiy npx tsc: chiqish kodi [:2], dist/ yangilandimi — [:ha].
  • Faqat tekshirish, npx tsc --noEmit: chiqish kodi .
  • Node bilan, node src/index.ts: chiqish kodi .

Keyin tsconfig.json ga "noEmitOnError": true qo'shing, dist/ ni o'chiring va npx tsc ni qayta ishga tushiring.

Yechim

Biz Node 24.21.0 va TypeScript 7.0.2 da tekshirdik:

bash
npx tsc; echo $?            # 2 — xato bor, dist/ yozildi
npx tsc --noEmit; echo $?   # 1 — xato bor, hech narsa yozilmadi
node src/index.ts; echo $?  # 0 — "800008000", tekshiruv yo'q

noEmitOnError bilan npx tsc — chiqish kodi 1, dist/ papkasi umuman yaratilmaydi. Xulosa: xato bo'lsa, faqat tsc "yo'q" deydi. Node uchun xato yo'q — u turlarga qaramaydi.

3-mashq (qiyin): Modul, skriptlar va test

addTip ni alohida modulga chiqaring va unga test yozing.

  1. src/tip.ts — export function addTip(…). Choy puli manfiy bo'lsa — RangeError("Choy puli manfiy bo'lishi mumkin emas").
  2. src/index.ts — import { addTip } from "./tip.ts";.
  3. test/tip.test.js — ikki test (node:test va assert): qo'shish va manfiy qiymatda RangeError. Test fayli JavaScript bo'lib qoladi, ../src/tip.ts ni Node o'zi o'qiydi.
  4. package.json skriptlari: build (tsc), tip (tsc --noEmit), start (node dist/index.js), test (node --test).

Ishora: npx tsc importdagi .ts kengaytmasiga xato beradi. Xabarni o'qing — kerakli bayroqning nomi xabarning ichida. Lekin u bayroq faqat tekshiradi, dist/index.js ichida esa import .js ga aylanishi kerak. Buning uchun boshqa bayroq bor: rewriteRelativeImportExtensions.

Yechim

src/tip.ts:

ts
// Choy puli: summaga qo'shiladi, manfiy bo'lishi mumkin emas
export function addTip(total: number, tip: number): number {
  if (tip < 0) {
    throw new RangeError("Choy puli manfiy bo'lishi mumkin emas");
  }
  return total + tip;
}

src/index.ts:

ts
// «Bahor» kassasi: buyurtma summasi va choy puli
import { addTip } from "./tip.ts";

const total = 35000 * 2 + 5000 * 2;
console.log(`Jami: ${total} so'm`);
console.log(`Choy puli bilan: ${addTip(total, 8000)} so'm`);

Birinchi npx tsc:

text
src/index.ts:2:24 - error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.

2 import { addTip } from "./tip.ts";
                         ~~~~~~~~~~


Found 1 error in src/index.ts:2

Tarjimasi: "Import yo'li .ts bilan faqat allowImportingTsExtensions yoqilganda tugashi mumkin". Lekin JavaScript yozadigan loyihada bu bayroqni yolg'iz yoqib bo'lmaydi — tsc TS5096 beradi: u faqat noEmit, emitDeclarationOnly yoki rewriteRelativeImportExtensions bilan birga ishlaydi. Birinchi ikkitasi JavaScript yozishni o'chiradi (emitDeclarationOnly — faqat .d.ts turlar fayllarini yozadi). Bizga uchinchisi kerak, chunki dist/ da import ./tip.js bo'lishi shart. U .ts importlariga o'zi ruxsat beradi. tsconfig.json ning yuqori qismi:

json
    "rootDir": "./src",
    "outDir": "./dist",
    "rewriteRelativeImportExtensions": true,
    "noEmitOnError": true,

rewriteRelativeImportExtensions — "nisbiy importdagi .ts ni .js ga almashtir". Endi npx tsc jim, dist/index.js da import { addTip } from "./tip.js";. Bir xil manba ikki yo'l bilan ishlaydi: node src/index.ts (Node .ts ni o'qiydi) va node dist/index.js (tayyor JavaScript). vazifalar ham aynan shu usulni oladi.

test/tip.test.js:

js
import { test } from "node:test";
import assert from "node:assert/strict";
import { addTip } from "../src/tip.ts";

test("choy puli summaga qo'shiladi", () => {
  assert.equal(addTip(80000, 8000), 88000);
});

test("manfiy choy puli — RangeError", () => {
  assert.throws(() => addTip(80000, -1), RangeError);
});

package.json dagi skriptlar:

json
  "scripts": {
    "build": "tsc",
    "tip": "tsc --noEmit",
    "start": "node dist/index.js",
    "test": "node --test"
  },

npm test ni ishga tushirganingizda bizda shunday chiqdi (millisekundlar sizda boshqacha):

text
✔ choy puli summaga qo'shiladi (0.6825ms)
✔ manfiy choy puli — RangeError (0.3798ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 113.6737

npm run build va npm start — Jami: 80000 so'm, Choy puli bilan: 88000 so'm. XATOLAR.md ga TS5097 va TS18003 ni qo'shing.

bash
git add 15/02-ornatish 15/XATOLAR.md
git commit -m "15/02: tsc build, noEmitOnError, tip moduli va testlari"

node_modules/ va dist/ commit qilinmaydi — ular kurs repo'sining .gitignore ida bo'lsin.

4-mashq: Vazifalar qadami — tsc bilan build

vazifalar 12/39 dan beri tsc bilan tekshiriladi (npm run tip, 9 modulda // @ts-check). Endi tsc uni yig'adi ham: dist/ ga JavaScript yozadi, GitHub Pages esa dist/ ni joylaydi. Hali bitta ham .ts fayl yo'q — bu qadam faqat "quvur"ni quradi. Keyingi darslarda modullar birma-bir .ts ga o'tadi va shu quvurdan o'tadi.

  • Branch: chore/tsc-build
  • Commit: chore: tsc bilan build — dist/, allowJs; Pages dist'ni joylaydi, tanasi: jsconfig.json → tsconfig.json; sw VERSIYA v5-1
  1. jsconfig.json → tsconfig.json (git mv): noEmit olib tashlanadi, checkJs: false, rootDir: ".", outDir: "dist", include: ["assets/js"], exclude: ["assets/js/vendor"], allowJs qoladi.
  2. package.json: "prebuild" (dist/ ni o'chiradi), "build": "tsc && node skriptlar/nusxala.js", "tip": "tsc --noEmit".
  3. skriptlar/nusxala.js (yangi) — tsc ga tegishli bo'lmagan fayllarni dist/ ga ko'chiradi.
  4. dist/ — .gitignore, .prettierignore va ESLint globalIgnores ga.
  5. .github/workflows/pages.yml (yangi) — GitHub Pages'ga Actions orqali deploy darsidagi shakl, path: dist.
  6. skriptlar/vendor.js web-vitals.d.ts ni ham yozadi; sw.js da VERSIYA = "v5-1".

Tekshiruv: npm run build, npm test, npm run tip, npm run lint, npm run format:check — hammasi exit 0.

Yechim

tsconfig.json (jsconfig.json o'rniga):

json
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false,
    "strict": true,
    "target": "es2024",
    "lib": ["esnext", "dom"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "rootDir": ".",
    "outDir": "dist"
  },
  "include": ["assets/js"],
  "exclude": ["assets/js/vendor"]
}

12/39 dagi fayldan farqi:

  • noEmit yo'q — endi tsc fayl yozadi, outDir: "dist" ga.
  • allowJs: true — .js fayllar ham dist/ ga o'tadi. Hali hammasi .js, shuning uchun busiz dist/ bo'sh qolardi.
  • checkJs: false — hamma faylni tekshirmaydi. Tekshiruv avvalgidek faqat 1-qatorida // @ts-check bor 9 modulda.
  • rootDir: "." — papkalar tuzilmasi saqlanadi: assets/js/api.js → dist/assets/js/api.js. Shuning uchun index.html dagi yo'llar o'zgarmaydi.
  • include endi bitta papka: ro'yxat o'rniga // @ts-check qatori qaror qiladi. vendor/ — boshqalarning kodi, uni yig'maymiz.

package.json skriptlari (o'zgargan qatorlar):

json
    "prebuild": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
    "build": "tsc && node skriptlar/nusxala.js",
    "tip": "tsc --noEmit",

npm build dan oldin prebuild ni o'zi ishga tushiradi (nomidagi pre shuni bildiradi). U eski dist/ ni o'chiradi: o'chirilgan modulning eski .js i dist/ da qolib ketmasin. node -e ichida fs moduli import qilmasdan ham bor. tip dagi -p jsconfig.json endi kerak emas: tsc tsconfig.json ni o'zi topadi.

skriptlar/nusxala.js — tsc faqat assets/js dagi modullarni yozadi. Sahifa, CSS, ikonlar, manifest, sw.js va vendor nusxasi o'zgarishsiz ko'chiriladi:

js
// skriptlar/nusxala.js — npm run build ning ikkinchi yarmi: tsc faqat
// assets/js dagi modullarni dist/ ga yozadi; sahifa, CSS, ikonlar,
// manifest, Service Worker va vendor nusxasi o'zgarishsiz ko'chiriladi.
// GitHub Pages faqat dist/ ni joylaydi (.github/workflows/pages.yml)
import { cpSync, readdirSync } from "node:fs";

const ildiz = new URL("../", import.meta.url);
const dist = new URL("dist/", ildiz);

const FAYLLAR = [
  "index.html",
  "manifest.webmanifest",
  "sw.js",
  "assets/css",
  "assets/ikonlar",
];
// vendor/: faqat .js — .d.ts brauzerga kerak emas
const VENDOR = readdirSync(new URL("assets/js/vendor/", ildiz))
  .filter((nom) => nom.endsWith(".js"))
  .map((nom) => `assets/js/vendor/${nom}`);

for (const yol of [...FAYLLAR, ...VENDOR]) {
  cpSync(new URL(yol, ildiz), new URL(yol, dist), { recursive: true });
}
console.log(
  `dist/ ga ko'chirildi: ${FAYLLAR.length + VENDOR.length} ta`,
);

Nega web-vitals.d.ts (o'lchandi). olchov.js ./vendor/web-vitals.js ni import qiladi. .d.ts bo'lmasa, tsc shu import orqali vendor faylni ham dasturga oladi va dist/ ga qayta formatlab yozadi. skriptlar/vendor.js endi yoniga ikki qatorli tur faylini ham yozadi:

ts
// web-vitals 6.2.3 turlari | npm run vendor
export * from "web-vitals";

tsc importda .d.ts ni .js dan oldin qidiradi. Tur fayli topilgach, .js dasturga kirmaydi va nusxala.js uni bayt-bayt ko'chiradi. .d.ts nima ekanini Declaration fayllari darsida batafsil ko'ramiz.

tsc JavaScript'ni ham qayta yozadi. dist/assets/js/api.js dagi bitta funksiya:

js
// manba: assets/js/api.js
function holatKodi(holat) {
  if (holat === 404) return "TOPILMADI";
  if (holat === 400 || holat === 422) return "NOTOGRI";
  if (holat >= 500) return "SERVER";
  return "HTTP";
}

// tsc natijasi: dist/assets/js/api.js
function holatKodi(holat) {
    if (holat === 404)
        return "TOPILMADI";
    if (holat === 400 || holat === 422)
        return "NOTOGRI";
    if (holat >= 500)
        return "SERVER";
    return "HTTP";
}

Xulq bir xil, matn boshqa: 4 bo'sh joy, return alohida qatorda, bo'sh qatorlar tushib qoladi, izohlar saqlanadi. dist/ — o'qish uchun emas, brauzer uchun. Kodni har doim manbada o'qing va tahrirlang.

.github/workflows/pages.yml — GitHub Pages'ga Actions orqali deploy darsidagi ikki bosqichli shakl: check (npm ci, test, lint, format:check, tip), keyin deploy (npm ci, npm run build, upload-pages-artifact — path: dist). Brauzer .ts ni o'qimaydi, shuning uchun saytga endi repo emas, build natijasi chiqadi. GitHub'da: Settings → Pages → Source → GitHub Actions (push'dan oldin).

Tekshiruv:

bash
npm run build
text
> prebuild
> node -e "fs.rmSync('dist', { recursive: true, force: true })"


> build
> tsc && node skriptlar/nusxala.js

dist/ ga ko'chirildi: 6 ta

dist/ da 28 ta fayl, JavaScript — 77 748 bayt. npm test — 137/137 (o'zgarmagan: testlar hali manba .js ni tekshiradi). tip, lint, format:check — toza. 14-qismdagi 159 ta brauzer tekshiruvi endi dist/ ustida o'tkazildi — 159/159. Lighthouse — 100 / 100 / 100 / 100. Ilova xulqi o'zgarmadi: biz faqat uni yig'ish usulini almashtirdik.

O'lchov: agar hamma fayl tekshirilsa. checkJs ni hamma 17 modulga yoqib ko'rdik (npx tsc --noEmit --checkJs, strict) — 249 xato, 8 faylda. strict siz — 40 ta. Eng ko'pi asosiy.js va render.js da — ikkalasi ham DOM bilan ishlaydi:

checkJs hamma modulga: 249 xato fayllar bo'yicha
  • asosiy.js116 xato
  • render.js86 xato
  • tema-tanlash.js12 xato
  • holat.js10 xato
  • marshrut.js9 xato
  • saqlash.js9 xato
  • olchov + sinxron7 xato

Manba: O'lchandi: tsc 7.0.2 --noEmit --checkJs (strict), vazifalar #02 holati, Node 24.21.0, 2026-10-06

Xato turlari: 106 tasi — TS18047 ("… is possibly 'null'": querySelector topmasligi mumkin), 72 tasi — TS7006 (parametr turi yozilmagan), 34 tasi — TS2339. Shuning uchun checkJs yoqilmadi: 249 xatoni bir kunda tuzatish xavfli. Ko'chish bosqichma-bosqich bo'ladi — har darsda bir necha modul, va har biri bilan bu raqam kamayadi.

Commit va PR:

bash
git switch -c chore/tsc-build
git mv jsconfig.json tsconfig.json
# tsconfig.json, package.json, nusxala.js, pages.yml, ignore fayllari
npm run build && npm test && npm run tip
npm run lint && npm run format:check
git add .
git commit -m "chore: tsc bilan build — dist/, allowJs; Pages dist'ni joylaydi" \
  -m "jsconfig.json → tsconfig.json; sw VERSIYA v5-1"
git push -u origin chore/tsc-build
gh pr create --fill
gh pr merge --merge

Birinchi -m — commit sarlavhasi (65 belgi, Git qoidasi bo'yicha ≤ 72), ikkinchisi — tanasi. Diff: 11 fayl, +122 −30.

Oldinga qarab: ikki TypeScript paketi. Obyekt turlari darsidagi qadamda ESLint .ts fayllarni ham tekshiradigan bo'ladi (typescript-eslint plagini). Plagin kompilyatorning dasturiy API'siga tayanadi, TypeScript 7.0 da esa bunday API yo'q — Microsoft uni 7.1 da va'da qilgan. TS 7.0 e'lonidagi rasmiy yo'l — package.json da ikki taxallus (alias):

json
    "@typescript/native": "npm:typescript@7.0.2",
    "typescript": "npm:@typescript/typescript6@6.0.2",

npx tsc — TypeScript 7.0.2 (build va tip), npx tsc6 — TypeScript 6.0.3 (faqat ESLint uchun). Hozircha (2026-yil oktabr) shunday. 7.1 da API chiqqach, yana bitta paket qoladi.

11. Real ishda

  • Har TypeScript loyihasi shu uch narsadan boshlanadi: typescript devDependency, tsconfig.json va package.json da build/tip (ba'zan typecheck) skriptlari. Ishga kirganingizda birinchi qaraladigan fayllar shular.
  • CI'da tsc --noEmit odatda lint va test yonida turadi — tur xatosi bilan PR birlashtirilmaydi.
  • Node backend'larda (24-qismdan) node fayl.ts va tsc --noEmit juftligi tobora ko'p uchraydi: build qadamisiz ishga tushirish, tekshiruv esa alohida.
  • Intervyu: "tsc va tsc --noEmit farqi?", "Node .ts faylni bajarganda turlarni tekshiradimi?", "Nega TypeScript devDependency?".

Xulosa

  • O'rnatish: npm install --save-dev --save-exact typescript@7.0.2, versiya — npx tsc --version. Global o'rnatish shart emas.
  • npx tsc --init — tsconfig.json. Bugun kerakli qatorlar: rootDir, outDir, strict.
  • npx tsc — tekshiradi va .js yozadi (xato bo'lsa ham — noEmitOnError bo'lmasa). npx tsc --noEmit — faqat tekshiradi.
  • node fayl.ts (Node 24) va tsx — turlarni o'chirib bajaradi, tekshirmaydi. enum Node'da ishlamaydi.
  • TS Playground — o'rnatishsiz sinash; saytdagi «Ishga tushir» ham tekshirmaydi.
  • vazifalar endi tsc bilan dist/ ga yig'iladi va Pages dist/ ni joylaydi.

Keyingi dars: Tur annotatsiyasi va tur chiqarish — turni qachon o'zingiz yozishingiz kerak va qachon TypeScript uni o'zi biladi.

Manbalar

  • TypeScript blogi: "Announcing TypeScript 7.0" (2026-07-08), "Announcing TypeScript 6.0" (2026-03-23) — devblogs.microsoft.com/typescript
  • TypeScript hujjatlari: "tsc CLI Options", "What is a tsconfig.json" — typescriptlang.org/docs
  • Node.js hujjatlari: "Modules: TypeScript" — nodejs.org/docs/latest-v24.x/api/typescript.html
  • TS Playground — typescriptlang.org/play
  • tsx — tsx.is
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
TypeScript'ni o'rnatish va ishga tushirish: tsc, tsconfig.json va Node 24 — IlmHamroh