strictNullChecks în TypeScript

Face din null și undefined tipuri separate: o valoare care poate lipsi trebuie verificată înainte de folosire.

Sintaxă
"compilerOptions": { "strictNullChecks": true }

tsc --strictNullChecks

Ce face strictNullChecks

Fără strictNullChecks, null și undefined se pot pune în orice variabilă: un string poate fi oricând null, iar greșeala apare abia la rulare („Cannot read properties of undefined”). Cu opțiunea pornită, null și undefined devin tipuri separate. Dacă o valoare poate lipsi, tipul ei trebuie să spună asta (string | null), iar tu trebuie să verifici înainte să o folosești.

Efectul se vede la funcțiile care pot să nu găsească nimic: Array.find întoarce T | undefined, document.querySelector întoarce Element | null. Verificarea se face cu if, ?., ?? sau, când știi sigur, cu !.

Implicit este false, dar devine true când strict este true. Este cea mai utilă verificare strictă: prinde o clasă întreagă de erori de rulare. strictPropertyInitialization și exactOptionalPropertyTypes au nevoie de ea.

Parametri

Parametru Descriere
true Activează verificarea.
false Dezactivează verificarea, chiar dacă "strict": true.
(lipsă) Ia valoarea lui strict: activă dacă strict este true, altfel inactivă.

Exemple

Exemplul 1: Valori care pot lipsi

find poate întoarce undefined, iar parametrul text poate fi null. Ambele sunt folosite fără verificare. Fără opțiune (--strictNullChecks false) același cod trece și se oprește abia la rulare.

// tsconfig.json
{
  "compilerOptions": {
    "strictNullChecks": true,
    "lib": ["es2022", "dom"]
  }
}

// index.ts
const orase = ["Iași", "Cluj", "Timișoara"];
const gasit = orase.find(o => o.startsWith("B"));
console.log(gasit.toUpperCase());

function lungime(text: string | null) {
  return text.length;
}
console.log(lungime(null));

Rezultat (tsc 5.9)

$ npx tsc --noEmit
index.ts(3,13): error TS18048: 'gasit' is possibly 'undefined'.
index.ts(6,10): error TS18047: 'text' is possibly 'null'.

Exemplul 2: Verificarea înainte de folosire

După if (gasit), TypeScript știe că gasit este string. Operatorii ?. și ?? dau o valoare de rezervă când lipsește ceva.

const orase = ["Iași", "Cluj", "Timișoara"];

const gasit = orase.find(o => o.startsWith("C"));
if (gasit) {
  console.log(gasit.toUpperCase());
}

function lungime(text: string | null): number {
  return text?.length ?? 0;
}
console.log(lungime("Brașov"), lungime(null));

const lipsa = orase.find(o => o.startsWith("B"));
console.log(lipsa ?? "niciun oraș cu B");

Rezultat

CLUJ
6 0
niciun oraș cu B

Greșeli frecvente

  • Să pui ! (non-null) peste tot ca să scapi de erori. Dacă valoarea chiar lipsește, programul se oprește la rulare, exact ce trebuia prevenit.
  • Să folosești || în loc de ?? pentru valori implicite: 0 || 10 dă 10, iar 0 ?? 10 dă 0.
  • Să oprești strictNullChecks și să păstrezi strictPropertyInitialization: tsc dă eroarea TS5052, pentru că a doua opțiune are nevoie de prima.

Comenzi înrudite

  • strict: Pornește dintr-o singură mișcare toate verificările stricte de tipuri (strictNullChecks, noImplicitAny și celelalte).
  • strictPropertyInitialization: Dă eroare pentru proprietățile de clasă declarate, dar care nu primesc valoare nici la declarare, nici în constructor.
  • noUncheckedIndexedAccess: Adaugă undefined la tipul valorilor citite cu index (note[0], stoc[„pere”]), pentru că ele pot lipsi.
  • exactOptionalPropertyTypes: O proprietate opțională (telefon?: string) poate lipsi, dar nu poate primi explicit valoarea undefined.