Mundarija (29)
- Bu darsda
- 1. Nega bu kerak?
- 2. allowJs va checkJs
- 2.1 Ikki bayroq — ikki ish
- 2.2 JavaScript ham tekshiriladi — JSDoc bo'yicha
- 2.3 JavaScript'da hamma parametr ixtiyoriy
- 3. Fayl-fayl ko'chirish tartibi
- 3.1 Barglardan ildizga
- 3.2 Har qadam — bir xil sikl
- 3.3 Strict'ni ham bosqichma-bosqich
- 4. Hozircha tuzatib bo'lmaydigan joy: @ts-expect-error
- 4.1 @ts-expect-error — "bu yerda xato bor, bilaman"
- 4.2 @ts-ignore — jim o'chirish
- 4.3 any — ko'chishning eng xavfli "yechimi"
- 5. ESLint'ni TypeScript bilan ulash
- 6. Ko'p uchraydigan xatolar
- 6.1 Hammasini bitta PR'da ko'chirish
- 6.2 JSDoc turlarini tashlab yuborish
- 6.3 TS2578: Unused '@ts-expect-error' directive.
- 6.4 @ts-ignore va any bilan "tez ko'chish"
- 6.5 Ko'chish paytida xulqni ham o'zgartirish
- 7. Mashqlar
- 1-mashq (oson): Direktivalar
- 2-mashq (o'rta): JSDoc'dan TypeScript'ga
- 3-mashq (qiyin): Amaliy tajriba — uch faylli loyihani ko'chirish
- 4-mashq: Vazifalar qadami — ko'chish yakuni
- 8. Real ishda
- Xulosa
- Manbalar
JavaScript'dan TypeScript'ga ko'chish: allowJs, checkJs va fayl-fayl o'tish
Qisqacha: Katta JavaScript loyihani bir kunda TypeScript'ga o'tkazish shart emas.
tsconfig.jsonda"allowJs": true—.jsva.tsfayllar yonma-yon yashaydi va birga yig'iladi."checkJs": trueyoki fayl boshidagi// @ts-check— JavaScript ham JSDoc izohlari bo'yicha tekshiriladi. Keyin fayllar birma-bir.tsga o'tadi: avval hech narsaga tayanmaydigan "barg" modullar, oxirida DOM va kirish fayli. Hozircha tuzatib bo'lmaydigan joy —// @ts-expect-errorbilan belgilanadi. OxiridaallowJso'chadi.
Bu darsda
allowJs,checkJsva// @ts-check/// @ts-nocheckfarqini bilasiz.- JSDoc turlarini TypeScript yozuviga aylantirasiz.
- Modullarni qaysi tartibda ko'chirish kerakligini bog'liqlik grafidan aniqlaysiz.
strictni bosqichma-bosqich yoqasiz,@ts-expect-errorva@ts-ignorefarqini bilasiz.vazifalarko'chishini yakunlaysiz: oxirgi modullar.ts,allowJso'chadi — 12 qadamda topilgan xatolarni jamlaysiz.
Oldin bilishingiz kerak: JSDoc va // @ts-check, tsconfig.json chuqur, Strict bayroqlar oilasi, Build: tsc, bundler'lar va tsgo, Async kod va xatolarni tiplash.
1. Nega bu kerak?
O'rnatish darsida vazifalar ning 17 modulida checkJs ni bir vaqtda yoqib ko'rgan edik: 249 xato, 8 faylda. Tasavvur qiling: shu 249 tani bitta commit'da tuzatish. Bir haftalik ish, yuzlab o'zgargan qator, kod sharhida hech kim tekshira olmaydigan PR. Bu vaqtda jamoa boshqa ish qila olmaydi — har o'zgarish ko'chish bilan to'qnashadi.
Haqiqiy kompaniyalar ham shu muammoga duch keladi: Airbnb, Slack kabi jamoalar katta JavaScript kodini TypeScript'ga bosqichma-bosqich, oylar davomida o'tkazgan. Sir — TypeScript'ning o'zi bunga imkon beradi: JavaScript va TypeScript fayllar bitta loyihada yonma-yon yashay oladi.
Hayotiy o'xshatish: «Bahor» oshxonasini ta'mirlash. Hammasini birdan buzib, bir oy yopib qo'yish mumkin. Yoki har hafta bitta burchakni ta'mirlab, oshxonani ishlatib turish mumkin. Ikkinchi yo'l sekinroq, lekin mijozlar hech qachon "yopiq" degan yozuvni ko'rmaydi.
2. allowJs va checkJs
2.1 Ikki bayroq — ikki ish
| Bayroq | Nima qiladi |
|---|---|
allowJs: true |
.js fayllar dasturga kiradi: .ts ulardan import qila oladi, tsc ularni outDir ga ko'chiradi |
checkJs: true |
.js fayllar ham tekshiriladi (JSDoc va tur chiqarish bo'yicha) |
// @ts-check |
faqat shu .js fayl tekshiriladi (checkJs siz ham) |
// @ts-nocheck |
shu fayl tekshirilmaydi (checkJs bo'lsa ham) |
allowJs siz .ts fayl .js ni import qilsa, tsc uni ko'rmaydi va tur ma'lumoti yo'q bo'ladi. allowJs bilan esa tsc JavaScript'ni o'qiydi va turlarni o'zi chiqaradi — xuddi .ts dagidek.
vazifalar aynan shunday yo'l tutdi:
- 12-qism (JSDoc va
// @ts-check) — 9 modulning tepasida// @ts-check,tsc --noEmit. - 15-qism, o'rnatish —
tsconfig.json:allowJs: true,checkJs: false. Hamma.jsdist/ga yig'iladi, tekshiruv — faqat// @ts-checkli fayllarda. - Keyingi qadamlar — fayllar birma-bir
.tsga. - Bugun — oxirgi fayllar,
allowJso'chadi.
2.2 JavaScript ham tekshiriladi — JSDoc bo'yicha
checkJs bilan .js fayldagi JSDoc izohlari — turlar. JSDoc darsida buni ko'rgansiz. Ko'chishda bu muhim: har JSDoc izohi — tayyor TypeScript turi, uni yo'qotmay, ko'chirish kerak.
JSDoc (.js) |
TypeScript (.ts) |
|---|---|
@param {number} price |
(price: number) |
@returns {string} |
(): string |
@typedef {{id: number}} Order |
type Order = { id: number } |
@template T |
<T> |
/** @type {Order} */ (x) |
x as Order |
@import { Order } from "./t.ts" |
import type { Order } from "./t.ts" |
Oxirgi ikki qatorga e'tibor bering. /** @type {X} */ (qiymat) — JSDoc'dagi assertion (qavslar majburiy). Ko'chishda uni as ga emas, imkon bo'lsa tekshiruvga aylantiring (TypeScript va DOM darsidagi instanceof). vazifalar da klasslar qadamida prefiks-daraxti dagi shunday assertion while (element !== undefined) tekshiruviga aylandi.
2.3 JavaScript'da hamma parametr ixtiyoriy
Bitta nozik farq bor. .js faylda JSDoc'siz parametrlar ixtiyoriy hisoblanadi: JavaScript'da funksiyani kamroq argument bilan chaqirish odatiy. Shuning uchun checkJs bilan ham withService(sum) (ikkinchi argument unutilgan) — xato emas. .ts da esa:
function withService(sum: number, rate: number): number {
return Math.round(sum * (1 + rate));
}
console.log(withService(70000));Kompilyator:
TS2554: Expected 2 arguments, but got 1.TypeScript aytyapti: "2 ta argument kutilgan edi, 1 ta berildi".
JavaScript'da bu chaqiruv xatosiz NaN berardi: 1 + undefined. Bu farqni 3-mashqda haqiqiy xatoda ko'rasiz: fayl .ts ga o'tgan zahoti yashirin bug ochiladi.
Tekshirib ko'ring:
allowJs: true,checkJs: falseva.jsfaylning birinchi qatorida// @ts-checkbor. Bu fayl tekshiriladimi?
Javob
Ha. // @ts-check — fayl darajasidagi "tekshir" belgisi, u checkJs: false ni shu fayl uchun bekor qiladi. Teskarisi ham bor: checkJs: true bo'lsa, // @ts-nocheck faylni tekshiruvdan chiqaradi. Bu ikki izoh ko'chish paytida "qaysi fayl tayyor" degan belgi bo'lib xizmat qiladi.
3. Fayl-fayl ko'chirish tartibi
3.1 Barglardan ildizga
Qaysi fayldan boshlash kerak? Javob — modullarning import grafidan (Modul semantikasi). Barg (leaf) modul — hech narsani import qilmaydigan yoki faqat turlarni import qiladigan modul. Uni birinchi ko'chirsangiz, unga tayangan hamma fayl darhol aniq turlarni oladi. Kirish fayli (asosiy.js) esa hamma narsani import qiladi — u oxirida.
vazifalar ko'chishi aynan shu tartibda bo'ldi:
flowchart TB
A["turlar.ts<br/>faqat turlar"] --> B["sinxron, holat,<br/>saqlash, marshrut"]
B --> C["vazifa, royxat,<br/>prefiks-daraxti"]
C --> D["qidiruv, saralash,<br/>taymer, api"]
D --> E["render, asosiy,<br/>tema-tanlash, fayl"]
E --> F["paket, olchov, tema<br/>allowJs o'chadi"]Sxemani pastga qarab o'qing: har qavat oldingilariga tayanadi. Ba'zi modulni ko'chirish hozircha imkonsiz bo'lsa (masalan, boshqa jamoaning ichki kutubxonasi), uning yoniga .d.ts yozish mumkin (Declaration fayllari): kod JavaScript'da qoladi, lekin unga tayangan .ts fayllar aniq turlarni oladi. vazifalar dagi vendor/web-vitals.d.ts — shunday fayl. Eng ko'p xato oxirgidan oldingi qavatda — DOM modullarida (219 ta): ular document dan kelgan null lar bilan to'la (TypeScript va DOM).
3.2 Har qadam — bir xil sikl
Har modul uchun bir xil besh qadam:
git mv fayl.js fayl.ts— tarix saqlanadi, git buni "nomi o'zgardi" deb ko'radi.npm run tip— xatolarni sanang. Ular sizga "nima qilish kerak" ro'yxatini beradi.- Turlarni yozing: avval parametrlar va eksport funksiyalar natijasi (
TS7006ko'pincha eng ko'p), keyinnullva toraytirish. npm test— xulq o'zgarmaganini testlar tasdiqlaydi. Ko'chish — xulqni o'zgartirmaydigan qayta tuzish (refactoring).- Bitta commit, bitta PR. Kichik PR'ni tekshirish oson.
vazifalar da har qadamda fayl nomi o'zgartirilganda (turlar yozilmasdan) shuncha xato chiqdi:
- holat, saqlash, marshrut29 xato
- 3 klass moduli53 xato
- qidiruv, saralash, taymer34 xato
- api33 xato
- 4 DOM moduli219 xato
- paket10 xato
- olchov, tema5 xato
Manba: O'lchandi: tsc 7.0.2 --noEmit, vazifalar v4.1 → v5 ko'chishi, har qadam holati, 2026-10-06
Jami 383 ta — boshidagi bir martalik o'lchovdan (249) ko'p. Sabab: .ts da qoidalar .js dagidan qattiqroq va qadamlar davomida qat'iy bayroqlar qo'shilib bordi. Lekin har qadam — bir kunlik ish. Va har qadamdan keyin npm test 137 (keyin 143) testdan o'tdi, 159 brauzer tekshiruvi — 159/159.
3.3 Strict'ni ham bosqichma-bosqich
Ko'chishning boshida strict ni o'chiq qoldirish mumkin: xatolar ancha kam. vazifalar da checkJs bilan: strict — 249, strict siz — 40. Ko'p jamoalar shunday yo'l tutadi:
strict: falsebilan hamma faylni.tsga o'tkazish.- Bayroqlarni birma-bir yoqish:
noImplicitAny, keyinstrictNullChecks(eng ko'p xato beradigani), keyin qolganlari (Strict bayroqlar oilasi).
vazifalar boshqa yo'lni tanladi: strict 12-qismdan beri yoqiq, fayllar kichik guruhlarda. Ikkalasi ham to'g'ri — loyiha hajmiga qarab. Yuz minglab qatorli loyihada birinchisi; kichigida ikkinchisi tezroq natija beradi.
Tekshirib ko'ring: Nega
asosiy.jsni birinchi bo'lib.tsga o'tkazish noqulay?
Javob
asosiy.js hamma modulni import qiladi. Ular hali .js bo'lsa, ularning turlari JSDoc'dan yoki tur chiqarishdan keladi — ko'pincha any. Natijada asosiy.ts dagi xatolar soni katta, turlar esa zaif bo'ladi, va har barg modul ko'chganda asosiy.ts ni qayta tuzatish kerak. Barglardan boshlasangiz, har modul o'zidan oldingilarning tayyor turlarini oladi.
4. Hozircha tuzatib bo'lmaydigan joy: @ts-expect-error
4.1 @ts-expect-error — "bu yerda xato bor, bilaman"
Ba'zan xato aniq, lekin tuzatish boshqa modulning ko'chishini kutadi. Butun faylni // @ts-nocheck qilish o'rniga bitta qatorni belgilaysiz:
function priceOf(dish: "osh" | "manti"): number {
return dish === "osh" ? 35000 : 30000;
}
// @ts-expect-error — somsa menyuga 16-oktabrda qo'shiladi
console.log(priceOf("somsa")); // 30000@ts-expect-error keyingi qatordagi xatoni o'chiradi. Izohda nega va qachon yozing — bu qarz, uni keyin qaytarasiz. Ishlash paytida esa xato baribir bor: "somsa" uchun 30000 — noto'g'ri narx.
Uning eng foydali xususiyati: xato yo'qolsa, direktivaning o'zi xato beradi:
function priceOf(dish: "osh" | "manti" | "somsa"): number {
return dish === "osh" ? 35000 : 30000;
}
// @ts-expect-error — somsa menyuga 16-oktabrda qo'shiladi
console.log(priceOf("somsa"));Kompilyator:
TS2578: Unused '@ts-expect-error' directive.Tarjimasi: "ishlatilmagan @ts-expect-error direktivasi". Somsa turga qo'shildi, xato yo'qoldi — tsc "endi bu izohni olib tashla" deydi. Qarz o'z-o'zidan ko'rinib qoladi.
4.2 @ts-ignore — jim o'chirish
Eski // @ts-ignore ham xatoni o'chiradi, lekin xato yo'qolganda hech narsa demaydi. Yillar o'tib kodda ma'nosiz @ts-ignore lar qoladi — va ular ostidagi qatorga keyin qo'shilgan yangi xatoni ham jimgina yashiradi. Qoida: faqat @ts-expect-error, doim izoh bilan. typescript-eslint'ning ban-ts-comment qoidasi (recommended ichida) @ts-ignore ni taqiqlaydi va @ts-expect-error ga izoh talab qiladi.
4.3 any — ko'chishning eng xavfli "yechimi"
Xatoni tez yo'qotish uchun : any yozish oson: function total(dishes: any). Lekin any yuqumli — u tegib o'tgan har qiymat ham tekshiruvsiz bo'ladi (any va unknown). Ko'chish paytidagi any — "keyin tuzataman" va'dasi, va u ko'pincha bajarilmaydi. Yaxshiroq yo'llar: aniq tur, unknown + tekshiruv, yoki vaqtincha @ts-expect-error (u hech bo'lmasa o'zini ko'rsatadi). vazifalar da no-explicit-any ESLint qoidasi yoqiq — bitta ham any yo'q.
5. ESLint'ni TypeScript bilan ulash
Tur annotatsiyasi darsida va'da qilgan edik: ESLint'ni TypeScript bilan ulash shu yerda. vazifalar da bu Obyekt turlari qadamida qilingan: typescript-eslint paketi (8.71.1).
// eslint.config.js (vazifalar, qisqartirildi)
import js from "@eslint/js";
import tseslint from "typescript-eslint";
export default defineConfig([
js.configs.recommended,
{
files: ["**/*.ts"],
extends: [tseslint.configs.recommended],
},
]);tseslint.configs.recommended — .ts fayllarni o'qiydigan tahlilchi (parser) va tavsiya etilgan qoidalar: no-explicit-any, no-unused-vars, ban-ts-comment va boshqalar. Ko'chish paytida .js va .ts fayllar bitta konfiguratsiyada yashaydi: js.configs.recommended — hammasiga, typescript-eslint — faqat **/*.ts ga.
Yana bir to'plam — tseslint.configs.stylistic. Unda o'sha va'da qilingan no-inferrable-types bor: const count: number = 0 kabi ortiqcha turni ko'rsatadi (TypeScript 0 dan o'zi number chiqaradi). Turli qoidalar (Async kod qadamidagi no-floating-promises) esa projectService bilan alohida yoqiladi — ular sekinroq, lekin turlarni biladi.
6. Ko'p uchraydigan xatolar
6.1 Hammasini bitta PR'da ko'chirish
Tuzatish: kichik qadamlar, har biri — testlardan o'tgan alohida PR.
6.2 JSDoc turlarini tashlab yuborish
Fayl .ts ga o'tdi, JSDoc'dagi @param {…} o'chirildi, lekin turlar yozilmadi — TS7006. Tuzatish: har @param turini parametr yoniga ko'chiring, tavsif qismi oddiy izoh bo'lib qolishi mumkin.
6.3 TS2578: Unused '@ts-expect-error' directive.
Bu yaxshi xabar: qarz o'z-o'zidan to'landi. Tuzatish: izohni o'chiring.
6.4 @ts-ignore va any bilan "tez ko'chish"
Tuzatish: @ts-expect-error + izoh; any o'rniga unknown yoki aniq tur.
6.5 Ko'chish paytida xulqni ham o'zgartirish
"Bir yo'la shu bug'ni ham tuzataman". Natija — PR'da ikki xil o'zgarish, testlar qizil bo'lsa, sababini topish qiyin. Tuzatish: avval ko'chiring (xulq o'zgarmasin), keyin alohida PR'da tuzating. vazifalar dagi har xulq farqi QADAM izohida alohida yozilgan.
7. Mashqlar
1-mashq (oson): Direktivalar
// @ts-expect-error ostidagi qatorda xato yo'q bo'lsa, tsc qaysi kodli xato beradi? TS[:2578]. Xato bor bo'lganda // @ts-ignore ning @ts-expect-error dan farqi bormi (ha/yo'q)? [:yo'q].
Yechim
TS2578: Unused '@ts-expect-error' directive. Xato bor bo'lganda ikkalasi bir xil — xatoni o'chiradi. Farq xato yo'qolganda chiqadi: @ts-expect-error aytadi, @ts-ignore jim qoladi. Shuning uchun @ts-ignore ishlatilmaydi.
2-mashq (o'rta): JSDoc'dan TypeScript'ga
12-qismdagi uslubda yozilgan funksiyani .ts ga ko'chiring:
/**
* @typedef {{ guest: string, people: number }} Booking
*/
/**
* Stol tanlash: odamlar soniga mos eng kichik stol
* @param {Booking} booking
* @param {number[]} tables stollardagi o'rinlar
* @returns {number | null} stol o'lchami yoki null
*/
export function pickTable(booking, tables) {
const fitting = tables.filter((size) => size >= booking.people);
return fitting.length ? Math.min(...fitting) : null;
}Ishora: @typedef → type; tables ni funksiya o'zgartirmaydi — readonly (Massiv va tuple).
Yechim
export type Booking = { guest: string; people: number };
// Stol tanlash: odamlar soniga mos eng kichik stol
// tables — stollardagi o'rinlar; mos stol yo'q bo'lsa — null
export function pickTable(
booking: Booking,
tables: readonly number[],
): number | null {
const fitting = tables.filter((size) => size >= booking.people);
return fitting.length ? Math.min(...fitting) : null;
}
const booking = { guest: "Dilshod aka", people: 5 };
console.log(pickTable(booking, [2, 4, 6, 8])); // 6
console.log(pickTable(booking, [2, 4])); // null@param lardagi tavsiflar oddiy izohga ko'chdi, turlar — parametr yoniga. @typedef — export type: endi boshqa fayllar uni import type { Booking } bilan oladi. readonly number[] — JSDoc'da yo'q edi, ko'chish paytida qo'shilgan aniqlik (xulq o'zgarmaydi).
3-mashq (qiyin): Amaliy tajriba — uch faylli loyihani ko'chirish
kurs/mashqlar/15/45-kochish/ — uch JavaScript fayl. kassa.js ni ishga tushiring: Jami: NaN so'm. Bug bor, lekin qayerda?
// narx.js — «Bahor» narxlari
export const PRICES = {
osh: 35000,
manti: 30000,
lagmon: 28000,
choy: 5000,
};
export function priceOf(dish) {
return PRICES[dish];
}// buyurtma.js — buyurtma summasi
import { priceOf } from "./narx.js";
export function total(dishes) {
return dishes.reduce((sum, dish) => sum + priceOf(dish), 0);
}
export function withService(sum, rate) {
return Math.round(sum * (1 + rate));
}// kassa.js — chek chiqarish
import { total, withService } from "./buyurtma.js";
const order = ["osh", "choy", "somsa"];
const sum = total(order);
console.log(`Jami: ${withService(sum)} so'm`);45-kochish/tsconfig.json:allowJs,checkJs,noEmit,strict,module: "nodenext",types: ["node"](4-qadamdagi testnode:testni import qiladi — usizTS2591),allowImportingTsExtensions. (Ildizdagitsconfig.jsonningexcludeiga"45-kochish"ni qo'shing.)npx tsc -p 45-kochish --pretty false— xatolarni sanang.strict: falsebilan-chi?- Barg modul —
narx.js→narx.ts. Taom nomlari turi:keyof typeof PRICES. Xatolarni qayta sanang. buyurtma.js→buyurtma.ts. Enditscnimani topadi?kassa.js→kassa.ts, buglarni tuzating (xizmat haqi — 10%),buyurtma.test.tsyozing.
Yechim
1-qadam. strict bilan — 7 xato: TS7006 ×6 (parametr turi yo'q) va bitta TS7053. strict: false bilan — 0. Ikkala holatda ham haqiqiy bug ko'rinmaydi: JavaScript'da parametrlar ixtiyoriy va turlar any.
2-qadam. narx.ts:
// narx.ts — «Bahor» narxlari
export const PRICES = {
osh: 35000,
manti: 30000,
lagmon: 28000,
choy: 5000,
};
export type DishName = keyof typeof PRICES;
export function priceOf(dish: DishName): number {
return PRICES[dish];
}
console.log(priceOf("lagmon")); // 28000keyof typeof PRICES — "osh" | "manti" | "lagmon" | "choy" (keyof va typeof): obyektga yangi taom qo'shilsa, tur o'zi kengayadi. buyurtma.js dagi import yo'li ./narx.ts bo'ladi. Xatolar — 5 (hammasi buyurtma.js da, TS7006). Oxirgi qator (console.log) — darsda sinash uchun, mashq faylida u yo'q: aks holda kassa.ts ishga tushganda chek oldidan ortiqcha 28000 chiqardi.
3-qadam. buyurtma.ts:
// buyurtma.ts — buyurtma summasi
import { priceOf, type DishName } from "./narx.ts";
export function total(dishes: readonly DishName[]): number {
return dishes.reduce((sum, dish) => sum + priceOf(dish), 0);
}
export function withService(sum: number, rate: number): number {
return Math.round(sum * (1 + rate));
}Xatolar — 2, va ikkalasi kassa.js da, garchi u hali JavaScript bo'lsa ham:
45-kochish/kassa.js(5,19): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'readonly ("choy" | "lagmon" | "manti" | "osh")[]'.
Type 'string' is not assignable to type '"choy" | "lagmon" | "manti" | "osh"'.
45-kochish/kassa.js(6,22): error TS2554: Expected 2 arguments, but got 1.Mana NaN ning ikki sababi: menyuda yo'q "somsa" (priceOf — undefined) va unutilgan rate (1 + undefined — NaN). kassa.js ga hech kim tegmadi — u import qilgan funksiyalar endi aniq turga ega, va checkJs chaqiruvlarni shu turlarga solishtirdi. Bu ko'chishning eng yoqimli lahzasi: yashirin buglar o'zi chiqib keladi.
4-qadam. kassa.ts:
// kassa.ts — chek chiqarish
import { total, withService } from "./buyurtma.ts";
import type { DishName } from "./narx.ts";
const SERVICE_RATE = 0.1;
const order: DishName[] = ["osh", "choy", "manti"];
const sum = total(order);
console.log(`Jami: ${withService(sum, SERVICE_RATE)} so'm`);node 45-kochish/kassa.ts — Jami: 77000 so'm. order ga DishName[] turi yozildi: endi "somsa" qo'shsangiz, tsc shu qatorni ko'rsatadi. Endi .js fayl qolmadi — allowJs va checkJs ni o'chiring. Yakuniy tsconfig.json da beshta qator qoladi: noEmit, strict, module, types, allowImportingTsExtensions.
buyurtma.test.ts:
import { test } from "node:test";
import assert from "node:assert/strict";
import { total, withService } from "./buyurtma.ts";
test("total: taomlar narxi yig'indisi", () => {
assert.equal(total(["osh", "choy"]), 40000);
assert.equal(total([]), 0);
});
test("withService: 10% va yaxlitlash", () => {
assert.equal(withService(70000, 0.1), 77000);
assert.equal(withService(28005, 0.1), 30806);
});npx tsc -p 45-kochish — toza, node --test 45-kochish/buyurtma.test.ts — bizda (Node 24.21.0):
✔ total: taomlar narxi yig'indisi (2.2693ms)
✔ withService: 10% va yaxlitlash (0.7217ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 312.9662Xatolar yo'li: 7 → 5 → 2 → 0. XATOLAR.md ga TS2578 va TS2554 (JS'dan ko'chganda ochiladigan) ni qo'shing:
git add 15/45-kochish 15/tsconfig.json 15/XATOLAR.md
git commit -m "15/45: uch fayl .ts ga — 7 → 0 xato, 2 bug"4-mashq: Vazifalar qadami — ko'chish yakuni
Ikkita JavaScript modul qoldi: olchov.js (Web Vitals) va tema.js (sahifa chizilishidan oldin temani qo'llaydigan skript). Ular ko'chgach, allowJs kerak emas.
- Branch:
chore/ts-tugadi - Commit:
chore: hamma modul .ts, allowJs o'chirildi; hujjatlar v5, tanasi:olchov.ts, tema.ts; README, AGENTS, TEXNIK-QARZ v5; sw VERSIYA v5-11
olchov.js→olchov.ts,tema.js→tema.ts;asosiy.tsdaimport("./olchov.ts").tsconfig.jsondanallowJsvacheckJsni olib tashlang.sw.jsni nima qilish kerakligini o'lchang (checkJs+lib: ["webworker"]).- Hujjatlar: README, AGENTS.md, TEXNIK-QARZ — v5.
- Toza o'rnatishda tekshiring:
rm -rf node_modules dist && npm ci.
Yechim
1-qadam: olchov.ts — nomi o'zgartirilganda 5 xato: TS7031 ×3 (destructuring parametrda — { name, value, rating } — tur yo'q), TS7053 va TS7006. Turlar web-vitals paketidan keladi — Build qadamidagi vendor/web-vitals.d.ts orqali:
// Turlar — vendor/web-vitals.d.ts orqali npm paketidan
import type { Metric } from "./vendor/web-vitals.js";
const BAHOLAR: Readonly<Record<Metric["rating"], string>> =
Object.freeze({
good: "yaxshi",
"needs-improvement": "yaxshilash kerak",
poor: "yomon",
});
// Pick: funksiyaga butun Metric emas, uch maydon yetadi (testda ham)
type Olchov = Pick<Metric, "name" | "value" | "rating">;
// CLS — o'lchovsiz son (siljish ulushi), qolganlari — millisekund
export function olchovMatni({ name, value, rating }: Olchov): string {Metric["rating"]— indexed access: kutubxonadagi"good" | "needs-improvement" | "poor".Recordbilan — har baho uchun matn shart: kutubxona yangi baho qo'shsa,tscaytadi.Pick<Metric, …>— Utility types: test butunMetricobyektini yasamasdan, uch maydonli obyekt beradi.
tema.ts — 0 xato. Bu oddiy skript: import/export yo'q, index.html da <script src="…/tema.js"> (modul emas — kechiktirilmasligi kerak). tsc uni skript deb biladi va dist/assets/js/tema.js ga "use strict"; qo'shib chiqaradi, export {} qo'shmaydi — tekshirildi.
2-qadam: tsconfig.json. Ikki qator olib tashlandi, izoh yangilandi:
{
// Ko'chish tugadi (15/#45): assets/js da faqat .ts (va .d.ts) —
// allowJs o'chirildi, JS fayl kompilyatsiyaga kirmaydi
"compilerOptions": {
"strict": true,assets/js da endi: 17 modul + turlar.ts + tema.ts (hammasi .ts) va trusted-types.d.ts.
3-qadam: sw.js JavaScript qoladi. O'lchov: checkJs + lib: ["webworker"] — 9 xato. self — WorkerGlobalScope deb ko'rinadi (ServiceWorkerGlobalScope emas), event.waitUntil va respondWith — oddiy Event da yo'q. Service Worker — ES modul emas (export {} qo'shilsa, ro'yxatdan o'tmaydi), unga alohida lib va tsconfig kerak. Qaror: hozircha JS, TEXNIK-QARZ 23 — PWA mavzusida (21-qism) qaytamiz. Ko'chishda hamma narsani .ts qilish maqsad emas — maqsad tekshiriladigan, xavfsiz kod.
4–5-qadamlar. README ("Build" bo'limi, modullar .ts, kod qoidalari), AGENTS.md (TS qoidalari: import type, .ts yo'l, any/as taqiqi, unknown, Natija, never; 143 test), TEXNIK-QARZ v5 (10-qator to'landi, yangilari: 23 — sw.js, 24 — ikki TypeScript, 25 — build faqat tsc, 26 — tekshiruv qo'lda). Toza o'rnatish: rm -rf node_modules dist && npm ci → npx tsc --version → Version 7.0.2.
Natija: npm test — 143/143 (33 suite), test:tarmoq 2/2. tip, lint, format:check — toza. Brauzer (dist/) — 159/159. Lighthouse 13.5.0 (mobil) — 100 / 100 / 100 / 100. dist/assets/js — 81 095 bayt (#02 da JavaScript manbaning o'zi — 77 748; +4 % — yangi tekshiruv kodi va izohlar, turlar esa o'chdi). Diff: 13 fayl, +184 −110.
git switch -c chore/ts-tugadi
git mv assets/js/olchov.js assets/js/olchov.ts
git mv assets/js/tema.js assets/js/tema.ts
# tsconfig.json, asosiy.ts importi, README, AGENTS, TEXNIK-QARZ
npm run build && npm test && npm run tip
npm run lint && npm run format:check
git add .
git commit -m "chore: hamma modul .ts, allowJs o'chirildi; hujjatlar v5" \
-m "olchov.ts, tema.ts; README, AGENTS, TEXNIK-QARZ v5; sw VERSIYA v5-11"
git push -u origin chore/ts-tugadi
gh pr create --fill
gh pr merge --mergeButun ko'chish — 12 qadam, raqamlarda. Biz (tsc 7.0.2 ning haqiqiy chiqishi bilan) har qadamda shuncha xato topdik:
| Qadam | Nima | Xato |
|---|---|---|
| O'rnatish | checkJs hammaga (o'lchov) |
249 / 40 strict siz |
type va interface |
interface VazifaMalumoti |
1 |
| Discriminated union | case'siz Saralash |
1 |
null va undefined |
3 modul / strictNullChecks |
29 / 9 |
| Klasslar | 3 klass moduli | 53 |
| Generic cheklovlar | 3 generic modul | 34 |
| Utility types | api.ts |
33 |
| Strict bayroqlar | noUncheckedIndexedAccess |
2 |
| TypeScript va DOM | 4 DOM moduli | 219 |
| API ma'lumotlari | paket.ts |
10 |
| Async kod | ESLint Promise qoidalari | 13 (1 haqiqiy) |
| Bu dars | olchov, tema / sw.js |
5 / 9 |
Ularning ko'pchiligi — TS7006 (tur yozilmagan) va TS18047 (null bo'lishi mumkin): "TypeScript'ga turni ayting" va "null ni tekshiring". Lekin orasida haqiqiy buglar ham bor edi: searchParams.get() ning null i, indeks tekshiruvi, ushlanmagan import() rad etilishi, server javobidagi versiya yo'qligi. Ilova xulqi esa hech bir qadamda buzilmadi — 137 eski test va 159 brauzer tekshiruvi har safar o'tdi.
8. Real ishda
- Ko'chish loyihalari — ishga kirganingizda eng ko'p uchraydigan vazifalardan biri: "eski JS modulni TS ga o'tkaz". Bugungi tartib (barglardan, kichik PR'lar, testlar) — aynan shu ish.
- Avtomatik vositalar — Airbnb'ning
ts-migratekabi vositalar fayllarni ommaviy.tsga o'tkazadi va xatolarni@ts-expect-errorbilan belgilab chiqadi. Keyin jamoa ularni birma-bir tuzatadi. Bu katta loyihada boshlang'ich nuqta, tayyor natija emas. - Kutubxonalar — ko'p npm paketlar hali JavaScript'da, turlari
.d.tsyoki@typesda (Uchinchi tomon kutubxonalarini tiplash).allowJsva JSDoc — ularning ichki ishida ham uchraydi (masalan, Svelte o'z manbasini JSDoc bilan yozadi). - Intervyu: "Katta JS loyihani TS'ga qanday ko'chirasiz?", "
allowJsvacheckJsfarqi?", "@ts-ignoreva@ts-expect-errorfarqi?".
Xulosa
allowJs—.jsva.tsyonma-yon;checkJsyoki// @ts-check— JavaScript ham JSDoc bo'yicha tekshiriladi.- JSDoc turlari — tayyor TypeScript turlari:
@param→ parametr turi,@typedef→type,@template→<T>. - Tartib — barglardan ildizga; har qadam:
git mv,tip, turlar,test, bitta PR. Ko'chish xulqni o'zgartirmaydi. strict— boshidan yoki bayroqma-bayroq;@ts-expect-error+ izoh (xato yo'qolsa —TS2578),@ts-ignorevaany— yo'q.vazifalar— 12 qadam, har birida testlar yashil; oxiridaallowJso'chdi,sw.js— asosli istisno.
Keyingi dars: TS xato xabarlarini o'qish va tuzatish — 15-qism davomida yig'ilgan xato daftarini jamlaymiz: eng ko'p uchraydigan kodlar va uzun xabarni pastdan yuqoriga o'qish usuli.
Manbalar
- TypeScript Handbook: "Migrating from JavaScript", "JS Projects Utilizing TypeScript", "JSDoc Reference" — typescriptlang.org/docs/handbook
- TypeScript 3.9 Release Notes: "
// @ts-expect-errorComments" - typescript-eslint: "Getting Started",
ban-ts-comment,no-inferrable-types, shared configs — typescript-eslint.io - Airbnb: "ts-migrate" — github.com/airbnb/ts-migrate
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!