webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
TypeScript · Lecția 3 din 6

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.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.