12-bo‘lim

tsconfig va strict

strict nimalarni yoqadi, metod va xossa yozuvining tengsizligi, target, lib va paths.

🕑 22 daqiqa o‘qish 📄 797 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. strict nimalarni yoqadi
  2. strict dagi teshik: metod va xossa yozuvi teng emas
  3. strict dan tashqaridagi foydali sozlamalar
  4. noUncheckedIndexedAccess
  5. exactOptionalPropertyTypes
  6. noImplicitReturns
  7. noUnusedLocals va noUnusedParameters
  8. target - qaysi JavaScript ga o'girish
  9. lib - qaysi standart kutubxona mavjud
  10. paths - import taxalluslari
  11. Tavsiya etiladigan boshlang'ich sozlama
  12. Xulosa

2-bobda tsconfig.json yaratdik va strict: true yozdik. Endi u aslida nimani yoqishini va yana nimalarni qo'shish kerakligini ko'ramiz.

Bu bobning markazida bitta hayratlanarli narsa turadi: strict: true bo'lsa ham, TypeScript ataylab qoldirilgan bitta xavfsiz bo'lmagan joyga ega - va u metod yozuvida yashiringan.

strict nimalarni yoqadi #

TS
export function salom(ism) {
  return "Salom, " + ism;
}
Terminal
echo "--- strict o_chiq ---"
tsc --noEmit --strict false && echo "xato yo_q"
echo "--- strict yoniq ---"
tsc --noEmit 2>&1 | fold -sw 74
Natija
--- strict o_chiq ---
xato yo_q
--- strict yoniq ---
src/imp.ts(1,23): error TS7006: Parameter 'ism' implicitly has an 'any'
type.

Bu - noImplicitAny. Ikkinchisi undan ham muhimroq:

TS
export function narxi(nomi: string): number | null {
  return nomi === "Olma" ? 12000 : null;
}

const x: number = narxi("Anor");
console.log(x);
Terminal
echo "--- strictNullChecks o_chiq ---"
tsc --noEmit --strictNullChecks false && echo "xato yo_q"
echo "--- yoniq ---"
tsc --noEmit 2>&1 | fold -sw 74
Natija
--- strictNullChecks o_chiq ---
xato yo_q
--- yoniq ---
src/nul.ts(5,7): error TS2322: Type 'number | null' is not assignable to
type 'number'.
  Type 'null' is not assignable to type 'number'.

strictNullChecks o'chiq bo'lsa, null va undefined har qanday turga mos keladi - ya'ni TypeScript ning eng katta foydasi yo'qoladi.

strict: true nimani o'z ichiga oladi strict ichida noImplicitAny - yashirin any taqiqlanadi strictNullChecks - null alohida tur strictFunctionTypes - faqat XOSSA yozuvida strictBindCallApply - bind/call/apply turlari strictPropertyInitialization - maydon to'ldirish noImplicitThis - this ning turi aniq bo'lsin useUnknownInCatchVariables - catch(e) unknown alwaysStrict - "use strict" qo'shiladi bitta satr sakkiztasini yoqadi strict TASHQARISIDA noUncheckedIndexedAccess massiv va indeks imzosiga | undefined exactOptionalPropertyTypes "yo'q" va "undefined" farqlanadi noImplicitReturns barcha yo'llar qiymat qaytarsin noUnusedLocals / noUnusedParameters ishlatilmagan o'zgaruvchi va parametr isolatedModules, verbatimModuleSyntax har birini alohida yozish kerak strict yoqilganda ham qoladigan teshik Metod yozuvi - ishlov(h: Hayvon): void - parametrni ikki tomonlama tekshiradi. Xossa yozuvi - ishlov: (h: Hayvon) => void - to'g'ri tekshiradi.
Bitta satr sakkizta sozlamani yoqadi, lekin eng foydali beshtasi tashqarida qoladi

strict dagi teshik: metod va xossa yozuvi teng emas #

5-bobda ko'rgan edik: obyektda funksiyani ikki xil yozish mumkin. Ular bir xil ko'rinadi, lekin tekshirilishi boshqa:

TS
class Hayvon {
  nomi = "hayvon";
}

class Mushuk extends Hayvon {
  miyovlaydi = true;
}

type MetodYozuv = { ishlov(h: Hayvon): void };
type XossaYozuv = { ishlov: (h: Hayvon) => void };

const mushukIshlov = (m: Mushuk): void => {
  console.log(m.miyovlaydi.toString());
};

const a: MetodYozuv = { ishlov: mushukIshlov };
const b: XossaYozuv = { ishlov: mushukIshlov };
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/variant.ts(17,25): error TS2322: Type '(m: Mushuk) => void' is not
assignable to type '(h: Hayvon) => void'.
  Types of parameters 'm' and 'h' are incompatible.
    Property 'miyovlaydi' is missing in type 'Hayvon' but required in
type 'Mushuk'.

Faqat 17-qator - XossaYozuv - xato berdi. 16-qator, MetodYozuv, jimgina o'tdi.

mushukIshlov Mushuk kutadi. MetodYozuv esa "men senga istalgan Hayvon beraman" deydi. Bu - yolg'on va'da:

TS
class Hayvon {
  nomi = "hayvon";
}

class Mushuk extends Hayvon {
  miyovlaydi = true;
}

type MetodYozuv = { ishlov(h: Hayvon): void };

const mushukIshlov = (m: Mushuk): void => {
  console.log(m.miyovlaydi.toString());
};

const a: MetodYozuv = { ishlov: mushukIshlov };
a.ishlov(new Hayvon());
Terminal
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/variant2.ts 2>&1 | grep -oE "TypeError.*" | head -1
Natija
tsc: xato yo_q
TypeError: Cannot read properties of undefined (reading 'toString')

strict: true yoqilgan, tsc jim, dastur yiqildi.

Bu xato emas, ataylab qilingan murosa

Standart kutubxonaning o'zi bunga tayanadi. Masalan:

Natija
interface Array<T> {
  push(...items: T[]): number;
}

Agar metodlar ham qat'iy tekshirilsa, Mushuk[] ni Hayvon[] ga berib bo'lmasdi - bu esa juda ko'p mavjud kodni buzardi.

Shuning uchun TypeScript metod yozuvini ikki tomonlama tekshiradi.

Amaliy xulosa: obyekt turida qayta chaqiruv (callback) maydonini ishlov: (h: Hayvon) => void shaklida - xossa yozuvida - e'lon qiling. Shunda strictFunctionTypes sizni himoya qiladi.

strictFunctionTypes o'chirilsa, xossa yozuvi ham o'tib ketadi:

TS
class Hayvon {
  nomi = "hayvon";
}
class Mushuk extends Hayvon {
  miyovlaydi = true;
}

type XossaYozuv = { ishlov: (h: Hayvon) => void };

const mushukIshlov = (m: Mushuk): void => {
  console.log(m.miyovlaydi.toString());
};

const b: XossaYozuv = { ishlov: mushukIshlov };
Terminal
tsc --noEmit --strictFunctionTypes false && echo "tsc: xato yo_q"
Natija
tsc: xato yo_q

strict dan tashqaridagi foydali sozlamalar #

noUncheckedIndexedAccess #

4-bobda indeks imzosi bilan ko'rgan edik; u massivga ham tegishli:

TS
const mahsulotlar = ["Olma", "Anor"];
const uchinchi: string = mahsulotlar[2];
console.log(uchinchi.toUpperCase());
Terminal
echo "--- standart ---"
tsc --noEmit && echo "xato yo_q"
tsx src/indeks.ts 2>&1 | grep -oE "TypeError.*" | head -1
echo "--- noUncheckedIndexedAccess ---"
tsc --noEmit --noUncheckedIndexedAccess 2>&1 | fold -sw 74
Natija
--- standart ---
xato yo_q
TypeError: Cannot read properties of undefined (reading 'toUpperCase')
--- noUncheckedIndexedAccess ---
src/indeks.ts(2,7): error TS2322: Type 'string | undefined' is not
assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.

exactOptionalPropertyTypes #

TS
type Mahsulot = { nomi: string; tavsif?: string };

const a: Mahsulot = { nomi: "Olma" };
const b: Mahsulot = { nomi: "Anor", tavsif: undefined };

console.log("tavsif" in a, "tavsif" in b);
Terminal
echo "--- standart ---"
tsc --noEmit && echo "xato yo_q"
tsx src/exact.ts
echo "--- exactOptionalPropertyTypes ---"
tsc --noEmit --exactOptionalPropertyTypes 2>&1 | fold -sw 74
Natija
--- standart ---
xato yo_q
false true
--- exactOptionalPropertyTypes ---
src/exact.ts(4,7): error TS2375: Type '{ nomi: string; tavsif: undefined;
}' is not assignable to type 'Mahsulot' with 'exactOptionalPropertyTypes:
true'. Consider adding 'undefined' to the types of the target's
properties.
  Types of property 'tavsif' are incompatible.
    Type 'undefined' is not assignable to type 'string'.

"tavsif" in a - false, "tavsif" in b - true. Ya'ni maydon yo'q va maydon bor, lekin undefined - bu ikki xil holat. Standart sozlamada TypeScript ularni farqlamaydi.

Object.keys, in, JSON.stringify esa farqlaydi. Shuning uchun bu sozlama foydali.

noImplicitReturns #

TS
export function daraja(n: number) {
  if (n > 10) return "yuqori";
  else if (n > 5) return "orta";
}
Terminal
echo "--- standart strict ---"
tsc --noEmit && echo "xato yo_q"
echo "--- noImplicitReturns ---"
tsc --noEmit --noImplicitReturns 2>&1 | fold -sw 74
Natija
--- standart strict ---
xato yo_q
--- noImplicitReturns ---
src/qaytish.ts(1,17): error TS7030: Not all code paths return a value.

Qaytish turi yozilmagani uchun TypeScript uni string | undefined deb xulosa qildi va shikoyat qilmadi. 5-bobdagi maslahat - qaytish turini yozish - bu yerda ham ishlaydi.

noUnusedLocals va noUnusedParameters #

TS
export function salom(ism: string, unvon: string): string {
  const yil = 2026;
  return "Salom, " + ism;
}
Terminal
echo "--- standart ---"
tsc --noEmit && echo "xato yo_q"
echo "--- tekshiruv yoniq ---"
tsc --noEmit --noUnusedLocals --noUnusedParameters 2>&1 | fold -sw 74
Natija
--- standart ---
xato yo_q
--- tekshiruv yoniq ---
src/ishlatilmagan.ts(1,36): error TS6133: 'unvon' is declared but its
value is never read.
src/ishlatilmagan.ts(2,9): error TS6133: 'yil' is declared but its value
is never read.
Ataylab ishlatilmagan parametr

Ba'zan parametr kerak, lekin ishlatilmaydi - masalan (xato, natija) da faqat natija kerak.

Bunday paytda nomni pastki chiziq bilan boshlang:

Natija
function ishlov(_xato: Error, natija: string): void

TypeScript _ bilan boshlanadigan nomlarga shikoyat qilmaydi.

target - qaysi JavaScript ga o'girish #

TS
const dokon = { manzil: { shahar: "Toshkent" } };
const shahar = dokon?.manzil?.shahar ?? "nomalum";
console.log(shahar);
Terminal
tsc --target es2022 --outDir dist22
echo "--- es2022 ---"
fold -sw 74 dist22/nishon.js
tsc --target es2016 --outDir dist16
echo "--- es2016 ---"
fold -sw 74 dist16/nishon.js
Natija
--- es2022 ---
"use strict";
const dokon = { manzil: { shahar: "Toshkent" } };
const shahar = dokon?.manzil?.shahar ?? "nomalum";
console.log(shahar);
--- es2016 ---
"use strict";
var _a, _b;
const dokon = { manzil: { shahar: "Toshkent" } };
const shahar = (_b = (_a = dokon === null || dokon === void 0 ? void 0 :
dokon.manzil) === null || _a === void 0 ? void 0 : _a.shahar) !== null &&
_b !== void 0 ? _b : "nomalum";
console.log(shahar);

es2016 da ?. va ?? mavjud emas, shuning uchun TypeScript ularni qo'lda yozilgan tekshiruvlarga aylantirdi.

targetQachon
es2022Zamonaviy Node.js va brauzerlar
es2020Kengroq qamrov kerak bo'lsa
es5Juda eski brauzerlar - bugun kamdan-kam

lib - qaysi standart kutubxona mavjud #

TS
const sonlar = [1, 2, 3];
console.log(sonlar.at(-1));
JSON
{
  "compilerOptions": {
    "target": "es2015",
    "lib": ["es2015"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true,
    "types": []
  },
  "include": ["src"]
}
Terminal
echo "--- standart lib ---"
tsc --noEmit && echo "xato yo_q"
tsx src/lib.ts
echo "--- lib: es2015 ---"
tsc -p tsconfig.eski.json 2>&1 | fold -sw 74
rm -f tsconfig.eski.json
Natija
--- standart lib ---
xato yo_q
3
--- lib: es2015 ---
src/lib.ts(2,1): error TS2584: Cannot find name 'console'. Do you need to
change your target library? Try changing the 'lib' compiler option to
include 'dom'.
src/lib.ts(2,20): error TS2550: Property 'at' does not exist on type
'number[]'. Do you need to change your target library? Try changing the
'lib' compiler option to 'es2022' or later.

Ikkita muhim narsa ko'rindi:

  • Array.prototype.at - es2022 dan boshlab mavjud;
  • console JavaScript ning o'zida yo'q. U brauzerda dom, Node.js da esa @types/node orqali keladi.

target chiqishga, lib esa kompilyator nimani mavjud deb hisoblashiga ta'sir qiladi. Ular alohida sozlamalar.

paths - import taxalluslari #

TS
export const QQS = 12;
TS
import { QQS } from "@yordam/narx";
console.log(QQS);
JSON
{
  "compilerOptions": {
    "target": "es2022",
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "@yordam/*": ["src/yordam/*"]
    }
  },
  "include": ["src"]
}
Terminal
echo "--- taxallussiz ---"
tsc --noEmit 2>&1 | fold -sw 74
echo "--- paths bilan ---"
tsc -p tsconfig.taxallus.json && echo "xato yo_q"
rm -f tsconfig.taxallus.json
Natija
--- taxallussiz ---
src/asosiy.ts(1,21): error TS2307: Cannot find module '@yordam/narx' or
its corresponding type declarations.
--- paths bilan ---
xato yo_q
paths faqat tsc ga tushuntiradi

paths - tur tekshiruvi uchun. Ish vaqtida Node.js @yordam/narx ni topa olmaydi.

Shuning uchun uni qurish vositasida ham takrorlash kerak:

VositaQayerda
Viteresolve.alias
webpackresolve.alias
JestmoduleNameMapper
Node.jspackage.json dagi imports

Ikki joyda saqlanadigan sozlama - doim xato manbai. Kichik loyihada nisbiy yo'l (../yordam/narx) yetarli.

Tavsiya etiladigan boshlang'ich sozlama #

Natija
{
  "compilerOptions": {
    "target": "es2022",
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "isolatedModules": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}

skipLibCheck: true - node_modules dagi .d.ts fayllarni tekshirmaydi. Ular sizniki emas va ularni tuzata olmaysiz, tekshirish esa qurish vaqtini sezilarli uzaytiradi.

Xulosa #

  • strict: true sakkizta sozlamani birdan yoqadi; eng muhimlari - noImplicitAny va strictNullChecks.
  • strictNullChecks o'chiq bo'lsa, null har qanday turga mos keladi - TypeScript ning asosiy foydasi yo'qoladi.
  • strictFunctionTypes metod yozuviga tegishli emas - ishlov(h: Hayvon): void ikki tomonlama tekshiriladi va ish vaqtida yiqilishi mumkin.
  • Obyekt turidagi qayta chaqiruvlarni xossa yozuvida (ishlov: (h) => void) e'lon qiling.
  • noUncheckedIndexedAccess massiv va indeks imzosidan olingan qiymatga | undefined qo'shadi.
  • exactOptionalPropertyTypes "maydon yo'q" va "maydon bor, qiymati undefined" holatlarini farqlaydi.
  • noImplicitReturns barcha yo'llar qiymat qaytarishini talab qiladi; _ bilan boshlangan parametrga shikoyat qilinmaydi.
  • target chiqish kodiga, lib esa kompilyator nimani mavjud deb bilishiga ta'sir qiladi - bular alohida sozlamalar.
  • console JavaScript ning o'zida yo'q; u dom yoki @types/node dan keladi.
  • paths faqat tsc uchun; qurish vositasida uni takrorlash kerak.
  • skipLibCheck: true deyarli har doim to'g'ri tanlov.
Amaliy topshiriq
  1. --strict false bilan turlanmagan parametrli funksiyani kompilyatsiya qiling, keyin strict bilan takrorlang.
  2. --strictNullChecks false bilan null ni songa berib ko'ring.
  3. Metod va xossa yozuvidagi ikkita turni yozib, qaysi biri xato berishini aniqlang.
  4. Metod yozuvli variantni ishga tushirib, dasturni yiqiting.
  5. --noUncheckedIndexedAccess bilan massivning mavjud bo'lmagan elementiga murojaat qiling.
  6. --exactOptionalPropertyTypes bilan tavsif: undefined yozib, TS2375 ni oling.
  7. Qaytish turi yozilmagan, to'liq bo'lmagan funksiya yozib, --noImplicitReturns bilan TS7030 ni chaqiring.
  8. --target es2016 bilan ?. ishlatilgan faylni o'girib, natijani o'qing.
  9. lib ni es2015 qilib, at() va console xatolarini ko'ring.
  10. O'z loyihangiz uchun tsconfig.json yozing va har bir sozlama nega kerakligini izohda yozib chiqing.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.