IlmHamroh
JavaScript Full-stack/15-qism. TypeScript33/47-dars19 daqiqa
Mundarija (31)

tsconfig.json chuqur: target, lib, module, moduleResolution va TypeScript 6/7 standartlari

Qisqacha: tsconfig.json — kompilyatorga "qaysi fayllarni, qanday qoidalar bilan tekshir va qanday JavaScript yoz" degan buyruq. target — chiqadigan JS versiyasi, lib — qaysi tayyor API'lar (Set.union, document) bor deb hisoblash, module va moduleResolution — import qanday yoziladi va qanday topiladi. TypeScript 6 va 7 da standartlar o'zgardi: strict sukut bo'yicha yoqiq, target — es2025, types — bo'sh, eski bayroqlar (target: es5, baseUrl, outFile) esa olib tashlangan.

Bu darsda

  • tsconfig.json ning tuzilishini (compilerOptions, include, exclude, extends) o'qiy olasiz va --showConfig bilan tekshirasiz.
  • target va lib farqini misol bilan ko'rsatasiz — va lib ishlash paytidagi API'ni qo'shmasligini bilasiz.
  • module va moduleResolution ni (nodenext, bundler) loyihaga qarab tanlaysiz.
  • rootDir/outDir va TypeScript 6 dagi o'zgarishni (TS5011) tushuntirasiz.
  • Internetdan olingan eski tsconfig dagi olib tashlangan bayroqlarni taniysiz va almashtirasiz.

Oldin bilishingiz kerak: TypeScript'ni o'rnatish va ishga tushirish, Rekursiv turlar va tur murakkabligi chegaralari, ESM import.

1. Nega bu kerak?

O'tgan darslarda turlar ichida "dasturlash" bilan shug'ullandik. Endi kompilyatorning o'zini sozlaymiz. TypeScript'ni o'rnatish darsida tsc --init yaratgan faylning faqat to'rt qatorini tushuntirgan edik va "butun faylni keyinroq qatorma-qator o'qiymiz" degandik. Bugun — o'sha kun.

Sardor yangi loyiha boshladi va tsconfig.json ni bir maqoladan ko'chirdi. Maqola 2022-yilda yozilgan edi:

json
{
  "compilerOptions": {
    "target": "es5",
    "moduleResolution": "node",
    "baseUrl": ".",
    "outDir": "dist"
  }
}

npx tsc (TypeScript 7.0.2) shunday javob berdi:

text
tsconfig.json(3,15): error TS5108: Option 'target=ES5' has been removed. Please remove it from your configuration.
tsconfig.json(4,25): error TS5108: Option 'moduleResolution=node10' has been removed. Please remove it from your configuration.
tsconfig.json(5,5): error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration.
  Use '"paths": {"*": ["./*"]}' instead.

TypeScript aytyapti: "target=ES5 bayrog'i olib tashlangan. Uni sozlamadan o'chiring". baseUrl haqidagi xabar esa o'rniga nima yozishni ham aytadi (paths). Uchta qator — uchta eskirgan qaror. Ularni o'chirib yuborish oson. Lekin o'rniga nima yozish kerak? Buning uchun har bir bayroq nima qilishini bilish kerak. Internetdagi tsconfig larning ko'pi TypeScript 4–5 davrida yozilgan, 2026-yilda esa standartlar boshqa.

2. tsconfig.json tuzilishi

2.1 To'rt asosiy qism

json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist"
  },
  "include": ["src"],
  "exclude": ["src/**/*.test.ts"]
}
Kalit Nima qiladi
compilerOptions kompilyator qoidalari — darsning asosiy qismi
include qaysi papka/fayllar tekshiriladi (standart — hammasi, **/*)
exclude include dan nimalar chiqariladi (standart — node_modules, outDir)
extends boshqa tsconfig dan meros: uning sozlamalari + sizniki ustidan

include va exclude da glob naqshlari ishlaydi: * — fayl nomidagi istalgan belgilar, ** — istalgan chuqurlikdagi papkalar. src/**/*.test.ts — "src ichidagi, qaysi papkada bo'lsa ham, .test.ts bilan tugaydigan fayllar".

Muhim nozik joy: exclude faylni faqat ro'yxatdan chiqaradi. Agar kiritilgan fayl uni import qilsa — u baribir tekshiriladi. Masalan, src/old.ts ni exclude ga yozdingiz, lekin src/index.ts da import { x } from "./old.js" qoldi — tsc old.ts ni ham ochadi va undagi xatolarni ko'rsatadi.

2.2 tsc aslida nimani ko'ryapti?

Sozlama murakkablashganda uchta buyruq yordam beradi:

Buyruq Nima ko'rsatadi
npx tsc --showConfig extends bilan birlashtirilgan yakuniy sozlama va fayllar ro'yxati
npx tsc --listFilesOnly tekshiriladigan barcha fayllar (standart kutubxona ham)
npx tsc --explainFiles har fayl nega kirgani: "include'ga mos keldi" yoki "import qilindi"

Yuqoridagi sozlama bilan (asosiy fayl tsconfig.base.json da strict va noUncheckedIndexedAccess) --showConfig shunday chiqardi:

json
{
    "compilerOptions": {
        "noUncheckedIndexedAccess": true,
        "outDir": "./dist",
        "rootDir": "./src",
        "strict": true
    },
    "files": [
        "./src/index.ts",
        "./src/menu.ts"
    ],
    "include": [
        "src"
    ],
    "exclude": [
        "src/**/*.test.ts"
    ]
}

Meros olingan ikki bayroq ham, o'zimiznikilar ham bitta ro'yxatda. src/__tests__/menu.test.ts — files da yo'q: exclude ishladi. --explainFiles esa src/menu.ts haqida ikki sabab yozdi: Imported via "./menu.js" from file 'src/index.ts' va Matched by include pattern 'src'.

3. target va lib: ikki xil savol

3.1 target — qaysi JavaScript yoziladi

target — tsc chiqaradigan JavaScript qaysi ECMAScript versiyasida bo'lishi. Yangi sintaksis eski versiyada yo'q bo'lsa, tsc uni eski usulda qayta yozadi. Bir xil kodni ikki target bilan kompilyatsiya qildik:

ts
let t: number | undefined;
t ??= 5;
class A { #x = 1; get x() { return this.#x; } }

target: es2025 (TypeScript 7 standarti) — deyarli o'zgarishsiz, faqat tur o'chdi: let t; t ??= 5; va #x joyida. target: es2017 — 2017-yilda ??= ham, #x ham yo'q edi:

js
var _A_x;
let t;
t !== null && t !== void 0 ? t : (t = 5);
class A {
    constructor() {
        _A_x.set(this, 1);
    }
    get x() { return __classPrivateFieldGet(this, _A_x, "f"); }
}
_A_x = new WeakMap();

??= — uzun shartga, #x — WeakMap va yordamchi funksiyaga (fayl boshida yana 5 qator __classPrivateFieldGet) aylandi. Bu sintaksisni pastga tushirish (downleveling). Kod ishlaydi, lekin uzunroq va sekinroq.

Qaysi target tanlanadi? Kod qayerda ishlashiga qarab: Node 24 va Chrome 154 — es2024 va undan yangisini to'liq biladi. Eski brauzerlarni qo'llash kerak bo'lsa — bu odatda bundler'ning ishi (16-qism). Kanon vazifalar — "target": "es2024".

3.2 lib — qaysi API'lar bor deb hisoblanadi

lib — TypeScript'ga "ishlash muhitida qaysi tayyor obyekt va metodlar bor" deb aytadi: Set.prototype.union (ES2025), Object.groupBy (ES2024), document (DOM). lib berilmasa, u target dan olinadi.

ts
// @ts-options: {"lib": ["es2024"]}
const title = document.title;
const menu = new Set(["osh"]).union(new Set(["manti"]));

Kompilyator:

text
TS2584: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.
TS2550: Property 'union' does not exist on type 'Set<string>'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2025' or later.
  • Birinchisi: "document nomi topilmadi. lib ga dom ni qo'shishni o'ylab ko'ring". DOM — brauzer API'si, u lib da alohida.
  • Ikkinchisi: "Set<string> turida union yo'q. lib ni es2025 yoki yangiroqqa o'zgartiring". union — ES2025 metodi.

Ikkala xabar ham tuzatishni o'zi aytyapti.

target va lib ni adashtirmang:

target lib
Nimaga ta'sir qiladi chiqadigan JS sintaksisi qaysi API turlari bor
??=, #x, class ha — eski usulga o'giradi yo'q
Set.union, Object.groupBy yo'q — hech qachon qo'shmaydi ha — turlar paydo bo'ladi
Ishlash paytiga ta'siri kod qanday yozilgani hech qanday

Oxirgi qator — keyingi bo'limdagi tuzoqning kaliti.

Tekshirib ko'ring: target: "es2017" va lib: ["es2024"] bo'lsa, Object.groupBy(...) tsc dan o'tadimi? Chiqqan .js eski Node'da ishlaydimi?

Javob

tsc dan o'tadi — lib da ES2024 turlari bor. Lekin chiqqan JS'da Object.groupBy(...) o'zgarishsiz qoladi: target sintaksisni o'giradi, metod qo'shmaydi. Object.groupBy yo'q eski Node'da — TypeError: Object.groupBy is not a function. lib — va'da, uni bajarish ishlash muhitiga bog'liq.

3.3 TypeScript ushlamaydigan tuzoq: lib — faqat va'da

Kanon vazifalar da "lib": ["esnext", "dom"] — "eng yangi hamma narsa". esnext — hali standartga kirmagan, lekin TypeScript turlari tayyor bo'lgan API'lar. Masalan, Map.prototype.getOrInsert:

ts
// @ts-options: {"lib": ["esnext", "dom"]}
const cache = new Map<string, number>();
console.log(cache.getOrInsert("osh", 35000));

tsc — xatosiz. Node 24.21.0 esa:

text
TypeError: cache.getOrInsert is not a function

TypeScript lib ga ishondi: "esnext da bor — demak, bor". Node 24 da bu metod hali yo'q (biz typeof Map.prototype.getOrInsert ni tekshirdik — "undefined"). Qoida: lib ni kod ishlaydigan muhitga moslang. Node 24 uchun — es2024 (yoki @types/node bilan); esnext ni tanlasangiz, yangi metodlarni ishlatishdan oldin ularni maqsad brauzer/Node'da tekshiring (JS versiyalari va brauzer mosligi).

4. module va moduleResolution: importlar qanday ishlaydi

4.1 Ikki savol

  • module — chiqadigan JS'da import/export qanday yoziladi: ESM (import) yoki CommonJS (require).
  • moduleResolution — import { x } from "./menu.js" dagi yo'lni tsc qanday faylga topadi.

Bugun ikkita qiymat juftligi muhim:

Loyiha module moduleResolution Importda kengaytma
Node'da ishlaydigan kod nodenext nodenext (o'zi) shart: "./menu.js"
Bundler (Vite, esbuild) orqali esnext yoki preserve bundler shart emas: "./menu"
flowchart TD
  A["Kod qayerda ishlaydi?"] --> B{"Bundler bormi?"}
  B -- "yo'q, Node to'g'ridan-to'g'ri" --> C["module: nodenext"]
  B -- "ha: Vite, esbuild" --> D["module: esnext yoki preserve"]
  C --> E["import ./menu.js — kengaytma shart"]
  D --> F["moduleResolution: bundler"]
  F --> G["import ./menu — kengaytmasiz ham bo'ladi"]

4.2 nodenext: Node qoidalari bilan

module: nodenext — "Node qanday qilsa, men ham shunday qilaman". Node ESM'da importda fayl kengaytmasi majburiy (ESM import) — tsc ham shuni talab qiladi. "./menu" deb yozsak:

text
src/index.ts(1,23): error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './menu.js'?

TypeScript aytyapti: "node16 yoki nodenext da ECMAScript importlarida nisbiy yo'llar kengaytma talab qiladi. ./menu.js ni nazarda tutdingizmi?" Diqqat: .ts emas, .js — chunki build'dan keyin Node .js faylni yuklaydi. (Mashqlar papkamizda allowImportingTsExtensions bilan .ts yozamiz — u yerda build yo'q, Node .ts ni o'zi ishga tushiradi. Bu farqni Modullar TypeScript'da darsida batafsil ko'ramiz.)

nodenext yana bir ishni qiladi: ESM yoki CommonJS ekanini package.json dagi "type" maydonidan oladi. Bir xil src/index.ts:

ts
import { price } from "./menu.js";
export const total = price * 2;

package.json da "type": "module" bo'lsa — chiqish xuddi shunday ESM. "type" bo'lmasa (yoki "commonjs") — CommonJS:

js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.total = void 0;
const menu_js_1 = require("./menu.js");
exports.total = menu_js_1.price * 2;

Kod bir xil, sozlama bir xil — farq faqat package.json da. O'rnatish darsidagi npm pkg set type=module buyrug'i shuning uchun muhim edi: npm 11 npm init -y endi "type": "commonjs" yozadi.

4.3 bundler: vosita yo'llarni o'zi hal qiladi

moduleResolution: bundler — "importlarni zamonaviy bundler'lar kabi o'qi": kengaytmasiz "./menu" ham, package.json dagi exports maydoni ham ishlaydi. Natijani bevosita Node'da ishga tushirmaysiz — uni Vite yoki boshqa vosita yig'adi (16-qism).

TypeScript 6 dan beri module yozilmasa — esnext, moduleResolution esa bundler bo'ladi. Buni biz "module": "amd" ni sinaganda ko'rdik: kompilyator "bundler faqat module preserve, commonjs yoki es2015+ bo'lganda ishlaydi" deb xato berdi — ya'ni yozilmagan moduleResolution aslida bundler edi.

Kanon vazifalar — "module": "esnext", "moduleResolution": "bundler": brauzer ilovasi, Node uni ishga tushirmaydi.

Tekshirib ko'ring: Node'da node dist/main.js bilan ishga tushadigan kichik skript uchun bundler tanlansa, nima bo'lishi mumkin?

Javob

tsc import "./menu" ni (kengaytmasiz) o'tkazib yuboradi va .js da ham shunday qoldiradi. Node ESM esa kengaytmasiz faylni topa olmaydi: ERR_MODULE_NOT_FOUND. bundler — yo'llarni keyin kimdir (bundler) to'g'rilashiga ishonadi. Node uchun nodenext xatoni oldindan, kompilyatsiyada ushlaydi.

5. rootDir va outDir

outDir — .js fayllar qayerga yoziladi. rootDir — manba papkasining "ildizi": outDir ichida papkalar tuzilishi undan boshlab takrorlanadi.

TypeScript 6 da standart o'zgardi: avval rootDir fayllardan taxmin qilinardi (hammasi src/ da bo'lsa — src/). Endi standart — tsconfig.json turgan papka (.). Taxmin qilinmagani uchun src/index.ts → dist/src/index.js bo'ladi — dist/index.js emas. TypeScript 7 bu holatni xato bilan bildiradi:

text
tsconfig.json(6,5): error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
  Visit https://aka.ms/ts6 for migration information.

TypeScript aytyapti: "tsconfig.json ning umumiy manba papkasi — ./src. Chiqish fayllari tuzilishini to'g'irlash uchun rootDir ni aniq belgilang". Fayllar baribir yoziladi — biz tekshirdik, dist/src/main.js va dist/src/shifts.js paydo bo'ldi. Lekin package.json dagi "start": "node dist/main.js" endi ishlamaydi. Tuzatish: "rootDir": "src" ni yozing — eski xulq qaytadi.

6. TypeScript 6 va 7: yangi standartlar

6.1 Nima o'zgardi

TypeScript 6.0 (2026-yil 23-mart) ko'p bayroqlarning standart qiymatini o'zgartirdi va eskilarini "eskirgan" deb belgiladi. TypeScript 7.0 (2026-yil 8-iyul) — Go tilida qayta yozilgan kompilyator — o'sha standartlarni oldi, eskirganlarini esa butunlay olib tashladi. Har bir qatorni npx -p typescript@7.0.2 tsc bilan o'zimiz tekshirdik:

Bayroq Yangi standart Qanday tekshirdik
strict true sozlamasiz faylda TS7006 (implicit any) chiqdi
target es2025 Set.union o'tdi, target: es2024 da — TS2550
module esnext (moduleResolution — bundler) kengaytmasiz import o'tdi
types [] @types/node o'rnatilgan papkada ham process — TS2591
rootDir . TS5011, dist/src/…
noUncheckedSideEffectImports true import "./missing.css" — TS2882

types: [] ga alohida e'tibor. Avval TypeScript node_modules/@types dagi hamma paketni avtomatik ulardi. Endi — hech birini. Node loyihasida "types": ["node"] ni o'zingiz yozasiz (mashqlar papkamizdagi kabi). Saytdagi bloklar ham types: [] bilan tekshiriladi — Node turlarisiz:

ts
const home = process.env.HOME;

Kompilyator:

text
TS2591: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.

TypeScript aytyapti: "process degan nom topilmadi. Node turlarini o'rnatish kerakmi?" Xabar endi ikki qadamni aytadi: paketni o'rnating va uni types ga qo'shing.

tsc --init (TypeScript 7.0.2) bulardan tashqari ikki qat'iy bayroqni yoqib qo'yadi — noUncheckedIndexedAccess va exactOptionalPropertyTypes. Ular strict ga kirmaydi; ularni keyingi darsda o'rganamiz.

6.2 Olib tashlangan bayroqlar

Eski bayroq TypeScript 7.0.2 xatosi O'rniga
target: es5 TS5108 es2015 va yuqori (amalda es2022+)
moduleResolution: node / node10 / classic TS5108 nodenext yoki bundler
module: amd / umd / system TS5108 ESM; eski formatlar — bundler ishi
baseUrl TS5102 paths (xabarning o'zi taklif qiladi)
outFile TS5102 bundler (16-qism)
downlevelIteration TS5102 kerak emas — es5 yo'q
esModuleInterop: false, alwaysStrict: false TS5108 yozmang — doim true

TypeScript 6 da "ignoreDeprecations": "6.0" bu xatolarni vaqtincha o'chirardi. TypeScript 7 da u yordam bermaydi — sinab ko'rdik, target: es5 bilan baribir TS5108. Rasmiy ko'chish yo'riqnomasi — xabardagi https://aka.ms/ts6 havolasi.

Tekshirib ko'ring: Eski loyihada "baseUrl": "." va import { api } from "utils/api" bor. TypeScript 7 da nima qilasiz?

Javob

baseUrl ni o'chirasiz va xabar taklif qilganidek "paths": { "*": ["./*"] } yozasiz — yoki yaxshirog'i, nisbiy import ("./utils/api.js"). paths faqat tur tekshiruvi uchun: chiqqan .js da "utils/api" o'zgarmaydi, Node uni topmaydi. Shuning uchun paths asosan bundler bilan ishlatiladi (Modullar TypeScript'da darsida).

7. Kanon vazifalar sozlamasini o'qiymiz

Endi haqiqiy loyihaning tsconfig.json ini (15-qism oxiridagi holati) to'liq tushuna olasiz. Izohlar — kanondagi asl izohlar:

jsonc
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "verbatimModuleSyntax": true,
    "rewriteRelativeImportExtensions": true,
    "target": "es2024",
    "lib": ["esnext", "dom"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "rootDir": ".",
    "outDir": "dist"
  },
  "include": ["assets/js"],
  "exclude": ["assets/js/vendor"]
}
Qator Nega shunday
target: es2024 Chrome 154 uchun pastga tushirish kerak emas
lib: esnext, dom brauzer ilovasi; esnext — «lib — faqat va'da» bo'limidagi ogohlantirish shu yerga ham tegishli
module: esnext + bundler brauzer ESM; Node bu fayllarni ishga tushirmaydi
rootDir: ".", outDir: "dist" assets/js/x.ts → dist/assets/js/x.js — index.html dagi yo'llar o'zgarmaydi
include / exclude faqat ilova kodi; vendor/ — tayyor kutubxona nusxasi

Qat'iy bayroqlar — keyingi dars (shu qadamda yoqilgan), erasableSyntaxOnly — enum va muqobillari, verbatimModuleSyntax va rewriteRelativeImportExtensions — Modullar TypeScript'da.

8. Ko'p uchraydigan xatolar

8.1 Internetdan eski sozlama

TS5108: Option 'target=ES5' has been removed., TS5102: Option 'baseUrl' has been removed. Tuzatish: «Olib tashlangan bayroqlar» jadvali bo'yicha almashtiring; eng yaxshisi — npx tsc --init dan boshlang.

8.2 lib da kerakli API yo'q

TS2550: … Try changing the 'lib' compiler option to 'es2025' or later. yoki TS2584: Cannot find name 'document'. Tuzatish: lib ga kerakli versiya yoki dom. Lekin avval: kod ishlaydigan muhitda bu API bormi?

8.3 types bo'sh — process topilmaydi

TS2591: Cannot find name 'process'. Tuzatish: npm i -D @types/node va "types": ["node"].

8.4 Node uchun importda kengaytma yo'q

TS2835: Relative import paths need explicit file extensions … Tuzatish: "./menu.js" (yoki loyiha bundler bilan bo'lsa — moduleResolution: bundler).

8.5 dist/src/… paydo bo'ldi

TS5011: The common source directory of 'tsconfig.json' is './src'. Tuzatish: "rootDir": "src".

9. Mashqlar

1-mashq (oson): Qaysi bayroq?

Har vaziyatga bayroq nomini yozing (bitta so'z):

  1. Chiqadigan JS'da ??= eski usulga o'girilsin:
  2. document ni tanimayapti:
  3. .js fayllar build/ papkasiga tushsin:
Yechim

target — sintaksisni pastga tushiradi. lib — API turlari (dom qo'shiladi). outDir — chiqish papkasi. rootDir esa outDir ichidagi tuzilishni belgilaydi.

2-mashq (o'rta): Eski sozlamani yangilang

Bu sozlama Node 24 da ishlaydigan skript uchun yozilgan, TypeScript 7 da esa ishlamaydi:

json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "outFile": "build/app.js",
    "downlevelIteration": true
  }
}

TypeScript 7 bilan ishlaydigan, ESM chiqaradigan, src/ → build/ sozlamani yozing.

Yechim
json
{
  "compilerOptions": {
    "target": "es2024",
    "module": "nodenext",
    "rootDir": "src",
    "outDir": "build",
    "types": ["node"]
  },
  "include": ["src"]
}
  • es5 → es2024: Node 24 uni to'liq biladi; downlevelIteration endi kerak emas (va yo'q).
  • module: nodenext — Node uchun; moduleResolution uni o'zi oladi. ESM uchun package.json da "type": "module".
  • outFile (hammasini bitta faylga) — olib tashlangan; buning o'rniga outDir. Bitta fayl kerak bo'lsa — bundler.
  • strict yozilmadi — TypeScript 7 da u standart. Lekin ko'p jamoalar uni baribir yozadi: sozlamani o'qigan odam darhol ko'rsin.

3-mashq (qiyin): Amaliy tajriba — o'z sozlamasi bilan loyiha

kurs/mashqlar/15/33-tsconfig/ — 02-ornatish/ kabi alohida loyiha (o'z tsconfig.json i bilan). Ildiz tsconfig.json dagi exclude ga "33-tsconfig" ni qo'shing — bu papka umumiy tekshiruvga kirmasin.

  1. tsconfig.base.json — umumiy qat'iy qoidalar: strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, types: ["node"], skipLibCheck.
  2. tsconfig.json — extends bilan; target: "es2022", module: "nodenext", rootDir, outDir: "dist"; include: ["src"]; testlar build'ga kirmasin.
  3. src/shifts.ts — shiftOf(hour) (16:00 dan — "kechki", oldin — "tush") va groupByShift(bookings) — Object.groupBy bilan.
  4. src/main.ts — uchta bron bilan groupByShift ni chaqirib, smenalardagi bronlar sonini chiqaradi.
  5. src/shifts.test.ts — ikki test.

33-tsconfig papkasida npx tsc --pretty false ni ishga tushiring, chiqqan xatoni sozlama bilan tuzating (kodga tegmasdan). Keyin node dist/main.js va testlar.

Yechim
json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "types": ["node"],
    "skipLibCheck": true
  }
}

tsconfig.json — yakuniy holati (target avval topshiriqdagidek es2022 edi; nega es2024 bo'lgani — pastda):

json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "target": "es2024",
    "module": "nodenext",
    "rootDir": "src",
    "outDir": "dist"
  },
  "include": ["src"],
  "exclude": ["src/**/*.test.ts"]
}
ts
// 33-tsconfig/src/shifts.ts — bronlarni smenalarga ajratish
export type Booking = {
  readonly guest: string;
  readonly hour: number;
};
export type Shift = "tush" | "kechki";

export function shiftOf(hour: number): Shift {
  return hour < 16 ? "tush" : "kechki";
}

export function groupByShift(bookings: readonly Booking[]) {
  return Object.groupBy(bookings, (b) => shiftOf(b.hour));
}
ts
// 33-tsconfig/src/main.ts — build natijasini ishga tushirish
import { groupByShift } from "./shifts.js";

const groups = groupByShift([
  { guest: "Dilshod aka", hour: 19 },
  { guest: "Malika", hour: 12 },
  { guest: "Bobur", hour: 20 },
]);
console.log(groups.kechki?.length, groups.tush?.length);

Avval, topshiriqdagi target: es2022 bilan, npx tsc --pretty false shunday dedi:

text
src/shifts.ts(13,17): error TS2550: Property 'groupBy' does not exist on type 'ObjectConstructor'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2024' or later.
src/shifts.ts(13,36): error TS7006: Parameter 'b' implicitly has an 'any' type.

Ikkinchi xato birinchisining oqibati: groupBy topilmagach, callback parametri turini oladigan joy qolmadi. lib yozilmagan — u target dan olindi (ES2022). Node 24 Object.groupBy ni biladi, demak "target": "es2024" to'g'ri tuzatish (faqat lib ni ko'tarish ham ishlardi, lekin target ham muhitga mos bo'lgani yaxshi). Shundan keyin npx tsc — chiqishsiz, dist/ da ikki fayl: main.js, shifts.js (test — exclude tufayli yo'q). rootDir ni olib tashlab ko'rsangiz — «rootDir va outDir» bo'limidagi TS5011 va dist/src/.

node dist/main.js — 2 1 (kechki smenada ikki, tushda bitta bron). Testlar .ts dan, build'siz:

ts
// 33-tsconfig/src/shifts.test.ts — build'ga kirmaydi (exclude)
import { test } from "node:test";
import assert from "node:assert/strict";
import { shiftOf, groupByShift } from "./shifts.ts";

test("shiftOf: 16:00 dan — kechki", () => {
  assert.equal(shiftOf(15), "tush");
  assert.equal(shiftOf(16), "kechki");
});

test("groupByShift: smenalar bo'yicha", () => {
  const groups = groupByShift([
    { guest: "Malika", hour: 12 },
    { guest: "Bobur", hour: 20 },
  ]);
  assert.deepEqual(groups.tush?.map((b) => b.guest), ["Malika"]);
  assert.equal(groups.kechki?.length, 1);
});

node --test src/shifts.test.ts bizda (Node 24.21.0):

text
✔ shiftOf: 16:00 dan — kechki (1.5888ms)
✔ groupByShift: smenalar bo'yicha (1.5946ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 282.0804

Test "./shifts.ts" ni import qiladi, main.ts esa "./shifts.js" ni. Birinchisini Node .ts dan to'g'ridan-to'g'ri o'qiydi (test build'ga kirmaydi). Ikkinchisi build qilinadi va dist/ da .js ni topadi. Bu "ikki xil import" ni Modullar TypeScript'da darsida rewriteRelativeImportExtensions bilan bittaga keltiramiz.

XATOLAR.md ga qo'shing: TS5108, TS5102 (olib tashlangan bayroqlar), TS5011 (rootDir), TS2550/TS2584 (lib), TS2591 (types), TS2835 (kengaytma). Keyin kurs/mashqlar papkasidan (33-tsconfig/dist ni .gitignore ga qo'shing):

bash
git add 15/tsconfig.json 15/33-tsconfig 15/XATOLAR.md
git commit -m "15/33: o'z tsconfig'i bilan loyiha — extends, target, rootDir"

10. Real ishda

  • Yangi loyiha — npx tsc --init yoki freymvork shabloni (Vite, Next.js) yaratgan tsconfig dan boshlanadi. Internetdagi eski namunalarni ko'chirmang: 2026-yilda ularning yarmi TS5108 beradi.
  • Monorepo va bir nechta muhit: brauzer kodi (lib: dom), server kodi (types: node), testlar — har biriga alohida tsconfig, umumiy qismi extends bilan. Vite + React shablonlarida aynan shunday: tsconfig.app.json va tsconfig.node.json (16–17-qismlarda).
  • Ko'chish (migration): katta loyihani TypeScript 7 ga o'tkazish ko'pincha shu darsdagi jadval bo'yicha boshlanadi: olib tashlangan bayroqlar, types, rootDir.
  • Intervyu: "target va lib farqi?", "moduleResolution: bundler va nodenext qachon?", "exclude qilingan fayl nega baribir tekshirildi?" — amaliy savollar.

Xulosa

  • tsconfig.json: compilerOptions + include/exclude + extends. Yakuniy holatni --showConfig, fayllar sababini --explainFiles ko'rsatadi.
  • target — chiqadigan sintaksis; lib — API turlari. lib API qo'shmaydi: esnext dagi metod Node'da bo'lmasa — TypeError.
  • Node uchun module: nodenext (kengaytma shart, ESM/CJS — package.json "type" dan); bundler uchun esnext + bundler.
  • TypeScript 6/7: strict: true, target: es2025, module: esnext, types: [], rootDir: "." — sukut bo'yicha. rootDir ni aniq yozing.
  • target: es5, moduleResolution: node, baseUrl, outFile — TypeScript 7 da olib tashlangan (TS5108/TS5102), ignoreDeprecations yordam bermaydi.

Keyingi dars: Strict bayroqlar oilasi — strict ichida nimalar bor, unga kirmaydigan noUncheckedIndexedAccess va exactOptionalPropertyTypes, va vazifalar da ular qancha xato topdi.

Manbalar

  • Microsoft, "Announcing TypeScript 6.0", 2026-03-23 — devblogs.microsoft.com/typescript/announcing-typescript-6-0/
  • Microsoft, "Announcing TypeScript 7.0", 2026-07-08 — devblogs.microsoft.com/typescript/announcing-typescript-7-0/
  • TypeScript 6 ko'chish yo'riqnomasi — aka.ms/ts6
  • TSConfig Reference — typescriptlang.org/tsconfig (target, lib, module, moduleResolution, rootDir, types)
  • TypeScript Handbook: "Modules — Choosing Compiler Options" — typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options.html
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
tsconfig.json chuqur: target, lib, module, moduleResolution va TypeScript 6/7 standartlari — IlmHamroh