null și undefined în TypeScript

Tipuri de bază TypeScript 2.0

Cu strictNullChecks, null și undefined sunt tipuri separate: o variabilă le acceptă doar dacă tipul ei le include.

Sintaxă
let x: string | null = null;
let y: number | undefined;
proprietate?: Tip;          // poate lipsi (undefined)

Ce face null și undefined

În JavaScript, null înseamnă „nicio valoare, intenționat”, iar undefined înseamnă „nu a primit valoare” (variabilă neinițializată, proprietate lipsă, funcție fără return). În modul strict (strictNullChecks), TypeScript le tratează ca tipuri separate: un string nu poate fi null.

Când o valoare poate lipsi, o spui în tip: string | null sau number | undefined. Un parametru sau o proprietate cu ? are automat și undefined în tip. Înainte să folosești valoarea, trebuie să verifici că nu este null/undefined: cu if, cu ?. sau cu ??.

Așa sunt prinse înainte de rulare cele mai frecvente erori din JavaScript: Cannot read properties of undefined. Metodele care pot să nu găsească nimic au tipuri care o spun: Array.find returnează T | undefined, document.querySelector returnează Element | null.

Exemple

Exemplul 1: Valoare care poate lipsi

find returnează Elev | undefined. După if (gasit), TypeScript știe că este un Elev.

interface Elev {
    nume: string;
    nota: number;
}
const elevi: Elev[] = [
    { nume: "Ana", nota: 9 },
    { nume: "Mihai", nota: 7 },
];

function cauta(nume: string): void {
    const gasit = elevi.find((e) => e.nume === nume);   // Elev | undefined
    if (gasit) {
        console.log(`${gasit.nume} are nota ${gasit.nota}`);
    } else {
        console.log(`${nume} nu este în listă`);
    }
}

cauta("Ana");
cauta("Ioana");

Rezultat

Ana are nota 9
Ioana nu este în listă

Exemplul 2: Fără verificare, tsc oprește codul

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

Eroarea afișată de tsc

exemplu.mts(3,13): error TS18048: 'gasit' is possibly 'undefined'.

Exemplul 3: null pus intenționat

null marchează că elevul nu are încă o notă. ?? dă o valoare de rezervă.

let notaFinala: number | null = null;
console.log("Notă:", notaFinala ?? "neîncheiată");
notaFinala = 9;
console.log("Notă:", notaFinala ?? "neîncheiată");

let oras: string | undefined;
console.log(oras === undefined, typeof oras);

Rezultat

Notă: neîncheiată
Notă: 9
true undefined

Greșeli frecvente

  • Folosești ! (non-null) ca să scapi de eroare fără să verifici. Dacă valoarea chiar lipsește, programul se oprește la rulare.
  • Verifici cu if (nota) o valoare numerică ce poate fi 0. Zero este fals, deci ramura se sare. Verifică explicit: nota !== null.
  • Folosești || pentru valori implicite: 0 || 10 dă 10. Pentru „doar dacă lipsește” folosește ??.

Comenzi înrudite

  • optional chaining (?.): a?.b citește proprietatea doar dacă a nu este null sau undefined; altfel întreaga expresie dă undefined.
  • nullish coalescing (??): a ?? b dă a, iar dacă a este null sau undefined dă b; spre deosebire de ||, păstrează 0, „” și false.
  • non-null (!): Semnul ! după o expresie îi spune compilatorului că valoarea nu este null sau undefined, fără verificare.
  • narrowing: TypeScript urmărește verificările din cod (if, switch, return) și restrânge tipul unei variabile în fiecare ramură.
  • NonNullable: NonNullable<T> elimină null și undefined din tipul T.