Atunci când primiți date dintr-o sursă externă nesigură (un răspuns de API fetch(), un fișier JSON de pe disc sau un payload de webhook), tipul inițial este unknown. O simplă funcție booleană clasică (function valida(x) { return true; }) verifică datele la runtime, dar nu informează compilatorul TypeScript despre noul tip al variabilei. Aici intervin Predicatele de Tip (Type Predicates) și Funcțiile de Aserțiune (Assertion Functions).
interface Administrator {
id: number;
rol: 'admin';
drepturiComplete: boolean;
}
// Funcție cu predicat de tip: 'val is Administrator' în loc de 'boolean'
function esteAdministrator(val: unknown): val is Administrator {
return (
typeof val === 'object' &&
val !== null &&
'rol' in val &&
(val as any).rol === 'admin'
);
}
function proceseazaCont(cont: unknown) {
if (esteAdministrator(cont)) {
// În interiorul acestui bloc IF, TypeScript știe 100% că 'cont' este Administrator!
console.log(`Admin logat cu drepturi: ${cont.drepturiComplete}`);
} else {
console.log("Contul nu este de tip administrator.");
}
}
2. Funcții de Aserțiune (Assertion Functions cu clauza asserts)
Introduse în TypeScript 3.7, funcțiile de aserțiune verifică o condiție și, în caz de eșec, aruncă o eroare (throw exception). Dacă funcția nu aruncă eroare, compilatorul restrânge automat tipul variabilei pentru restul scope-ului funcției apelante, fără a mai necesita un bloc if (...) suplimentar:
// Funcția garantează că valoarea nu este null sau undefined:
function afirmaNonNullable<T>(val: T, mesaj?: string): asserts val is NonNullable<T> {
if (val === null || val === undefined) {
throw new Error(mesaj || "Valoarea nu poate fi null sau undefined!");
}
}
function trimiteNotificare(email: string | null) {
// email este string | null
afirmaNonNullable(email, "Email-ul lipsește din sesiune!");
// DIN ACEST PUNCT, email este garantat exclusiv 'string':
console.log(`Trimis către: ${email.toLowerCase()}`);
}
Filtrarea Curată a Array-urilor cu Type Predicates
Un caz clasic de utilizare este filtrarea elementelor null sau undefined dintr-un array. Fără un predicat de tip, array.filter(Boolean) returnează în continuare (T | null)[]:
const lista: (string | null)[] = ['București', null, 'Cluj', null];
// PREDICAT DE TIP ÎN CALLBACK:
const oraseValide = lista.filter((oras): oras is string => oras !== null);
// oraseValide este inferat corect ca: string[] (fără niciun null!)