Union types și narrowing
Union, literal types, typeof/in/instanceof, discriminated unions și never.
Actualizat
Ce este un union type
Un union spune: valoarea poate fi unul dintre mai multe tipuri.
type Id = string | number
type Status = 'idle' | 'loading' | 'success' | 'error'E unul dintre cele mai folosite instrumente din TS: statusuri, variante de componente, răspunsuri care pot fi succes sau eroare.
Ce este narrowing
Dacă o valoare e string | number, TS te lasă să folosești doar ce e comun ambelor. Ca să folosești metode de string, trebuie să demonstrezi că e string. Asta e narrowing („îngustare”): un if după care TS știe tipul exact.
function format(id: string | number) {
id.toUpperCase() // ✗ number nu are toUpperCase
if (typeof id === 'string') {
return id.toUpperCase() // ✓ aici TS știe: string
}
return id.toFixed(0) // ✓ aici: number
}Tipuri de narrowing — și când
| Verificare | Pentru | Exemplu |
|---|---|---|
typeof x === 'string' |
primitive | string | number |
x === null, x !== undefined, if (x) |
valori lipsă | User | null |
'key' in x |
obiecte cu forme diferite | Cat | Dog |
x instanceof Error |
clase | catch (e) |
Array.isArray(x) |
array vs altceva | string | string[] |
x.kind === 'circle' |
discriminated unions | vezi mai jos |
funcție x is T |
verificare refolosibilă | isUser(x) |
Discriminated unions — cel mai util pattern
Fiecare variantă are un câmp comun cu o valoare literală diferită (discriminantul). Un switch pe el îngustează automat:
type Result =
| { status: 'success'; data: User }
| { status: 'error'; message: string }
| { status: 'loading' }
function render(r: Result) {
switch (r.status) {
case 'success': return r.data.name // TS știe că există data
case 'error': return r.message // aici message
case 'loading': return 'Se încarcă…'
}
}Imposibil să citești data într-o stare de eroare — o clasă întreagă de bug-uri dispare. Același pattern descrie acțiunile unui reducer în React.
Verificare exhaustivă cu never
Dacă adaugi mai târziu { status: 'empty' }, vrei ca TS să-ți arate toate switch-urile care nu o tratează:
default: {
const unreachable: never = r // ✗ eroare dacă a rămas o variantă netratată
return unreachable
}Type predicates
O funcție care verifică un tip și „îi spune” lui TS rezultatul:
function isString(x: unknown): x is string {
return typeof x === 'string'
}
const values: unknown[] = ['a', 1, 'b']
const strings = values.filter(isString) // string[]Pe scurt
- Union = „unul dintre”; literal unions pentru statusuri și variante.
- Narrowing =
typeof,in,instanceof, egalitate — dupăif, TS știe tipul. - Discriminated unions +
switch+never= cod fără stări imposibile.