Ce face narrowing
Narrowing (restrângerea tipului) înseamnă că TypeScript citește condițiile din codul tău și știe, în fiecare ramură, ce tip mai poate avea o variabilă. Dacă x este string | number și ai scris if (typeof x === "string"), în interiorul lui if x este string, iar în else este number. Analiza se numește control flow analysis.
Restrâng tipul: typeof, instanceof, in, comparațiile cu ===/!== (inclusiv cu null), verificarea de adevăr (if (x)), Array.isArray, switch pe o proprietate comună (discriminated unions), funcțiile predicat și asserts.
Contează și ieșirile din funcție: după if (!x) return;, restul funcției știe că x nu este gol. La atribuire, tipul se restrânge la valoarea atribuită. Atenție: restrângerea se pierde în interiorul unui callback care rulează mai târziu, dacă variabila este let și se poate schimba între timp.
Exemple
Exemplul 1: Mai multe feluri de restrângere
function descrie(x: string | number | string[] | null): string {
if (x === null) return "nimic";
if (typeof x === "number") return `număr ${x.toFixed(2)}`;
if (Array.isArray(x)) return `listă: ${x.join(" / ")}`;
return `text de ${x.length} caractere`; // aici a rămas doar string
}
console.log(descrie(null));
console.log(descrie(3.14159));
console.log(descrie(["Iași", "Cluj"]));
console.log(descrie("TypeScript"));
Rezultat
nimic
număr 3.14
listă: Iași / Cluj
text de 10 caractere
Exemplul 2: Ieșire devreme din funcție
După verificarea de la început, email este sigur string în tot restul funcției.
interface Elev {
nume: string;
email?: string;
}
function trimite(e: Elev): string {
if (!e.email) {
return `${e.nume} nu are email`;
}
const domeniu = e.email.split("@")[1];
return `Trimis către ${e.email} (domeniul ${domeniu})`;
}
console.log(trimite({ nume: "Ana", email: "ana@scoala.ro" }));
console.log(trimite({ nume: "Mihai" }));
Rezultat
Trimis către ana@scoala.ro (domeniul scoala.ro)
Mihai nu are email
Exemplul 3: Fără verificare, ambele variante rămân posibile
function lungime(x: string | string[] | undefined): number {
return x.length;
}
console.log(lungime("Ana"));
Eroarea afișată de tsc
exemplu.mts(2,12): error TS18048: 'x' is possibly 'undefined'.
Greșeli frecvente
- Verifici
if (nota)pentrunumber | undefined. Valoarea 0 este falsă și ramura se sare; compară explicit cuundefined. - Verifici tipul într-o funcție separată care returnează
boolean. TypeScript nu știe ce înseamnă rezultatul; transformă funcția în predicat (x is Tip).
Comenzi înrudite
type guards: Verificări la rulare pe care TypeScript le înțelege și după care știe tipul exact al unei valori.typeof guard: Verificarea typeof x === „string” (sau „number”, „boolean”…) restrânge tipul la primitivul respectiv.discriminated unions: Un union de obiecte cu o proprietate comună de tip literal; verificarea ei arată exact ce variantă ai.predicat de tip (is): O funcție cu rezultatul x is Tip spune compilatorului că, dacă returnează true, x are tipul Tip.union (|): Un tip care acceptă valori din mai multe tipuri: A | B înseamnă fie A, fie B.