Skip to content

Restrângerea tipurilor în TypeScript explicate

Modurile în care TypeScript restrânge un tip în interiorul unei ramuri, grupate după tehnică: gărzi integrate, predicate proprii, funcții de aserțiune, uniuni discriminate, egalitate și fluxul valorilor de adevăr, precum și restrângerea prin aliasuri și cea amânată. Fiecare rând asociază tehnica cu un exemplu dintr-o linie.

Restrângerea (narrowing) este modul în care TypeScript transformă un tip larg într-unul mai îngust în interiorul unei ramuri de cod, astfel încât să poată dovedi că un acces la o proprietate este sigur. Fiecare verificare (typeof, in, un predicat, un discriminant) îi spune compilatorului: de aici, valoarea este mai specifică. Tehnicile de mai jos sunt setul de lucru.

Tabel de referință · 23 intrări
23 of 23 rows
Gărzi integrate
Restrânge tipurile primitive: string, number, boolean și altele.if (typeof x === 'string') x.toUpperCase()
Restrânge la o instanță de clasă sau a unui constructor.if (e instanceof Error) e.message
Restrânge verificând că o proprietate există pe valoare.if ('id' in obj) obj.id
Restrânge orice valoare la un array; restrânge o uniune la membrul său de tip array.if (Array.isArray(x)) x.map(f)
Gărzi proprii
O funcție predicat a cărei valoare returnată restrânge argumentul.function isUser(x): x is User { return !!x.id }
Un predicat poate restrânge la o uniune de tipuri, nu doar la unul singur.function isKey(x): x is string | number
Un predicat de intersecție păstrează tipul de intrare și adaugă câmpuri la el.function hasId(x): x is x & { id: string }
O funcție de aserțiune care aruncă excepție dacă x nu este de tipul dat.function assertUser(x): asserts x is User
Uniuni discriminate
Restrânge o uniune după un câmp literal comun, prin switch sau if.type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
Fiecare caz restrânge la un singur membru al uniunii.switch (u.kind) { case 'a': u.a }
Restrânge o uniune fără etichetă când o proprietate există doar pe un membru.if ('b' in u) u.b
Fiecare caz este o condiție; cazul potrivit restrânge valoarea.switch (true) { case typeof x === 'string': }
Cazul implicit atribuie la never, dovedind că switch-ul este exhaustiv.default: { const x: never = u }
Egalitate și flux
Elimină null și undefined după o verificare de egalitate.if (x === null) return; x.toFixed()
Elimină valorile falsy (0, '', null, undefined, NaN).if (!x) return; // x is defined here
O proprietate truthy în lanț dovedește că valoarea de bază este prezentă.if (user?.active) user.name
Aserțiunea non-null elimină null și undefined fără nicio verificare.x!.toFixed(2)
Atribuire definită: declară că x este atribuit înainte de a fi citit.let name!: string; init()
Restrângerea se aplică în interiorul ramurii și după returnările timpurii.if (!arr) return; arr.map(...)
Aliasuri și amânare
Un const boolean care reține o verificare restrânge oriunde este testat.const isStr = typeof x === 'string'; if (isStr) …
O variabilă const își păstrează restrângerea în closures care o capturează.const s = get(); if (s) use(() => s.length)
Din TS 5.4, un let sau un parametru își păstrează restrângerea în closures după ultima sa atribuire.let n: string | null = get(); if (n) use(() => n.length)
unknown nu poate fi folosit până când un guard nu îl restrânge la un tip real.if (typeof u === 'string') u.length