union (|) în TypeScript

Un tip care acceptă valori din mai multe tipuri: A | B înseamnă fie A, fie B.

Sintaxă
let id: number | string;
type Stare = "activ" | "inactiv" | "suspendat";
function f(x: string | string[]) { ... }

Ce face union (|)

Un union se scrie cu bara verticală și înseamnă „una dintre variante”: number | string acceptă și numere, și texte. Este felul TypeScript de a descrie valori care pot avea mai multe forme: un id numeric sau text, un parametru care primește un element sau o listă, o stare din câteva valori fixe.

Pe o valoare union poți folosi direct doar ce au în comun toate variantele. Ca să folosești ce este specific unei variante, verifici întâi care este (typeof, Array.isArray, in, o proprietate comună), iar TypeScript restrânge tipul în fiecare ramură.

Union-urile de obiecte cu o proprietate comună de tip literal (tip: "cerc" | "patrat") se numesc discriminated unions și sunt cel mai sigur mod de a modela date cu variante.

Exemple

Exemplul 1: Parametru care acceptă un element sau o listă

function formateaza(nume: string | string[]): string {
    if (Array.isArray(nume)) {
        return nume.join(", ");      // aici nume este string[]
    }
    return nume.toUpperCase();       // aici nume este string
}

console.log(formateaza("Ana"));
console.log(formateaza(["Ana", "Mihai", "Ioana"]));

Rezultat

ANA
Ana, Mihai, Ioana

Exemplul 2: Doar ce au în comun toate variantele

toFixed există doar pe number, deci nu poate fi apelată pe number | string fără verificare.

function afiseaza(pret: number | string) {
    console.log(pret.toFixed(2));
}
afiseaza(12);

Eroarea afișată de tsc

exemplu.mts(2,22): error TS2339: Property 'toFixed' does not exist on type 'string | number'.
  Property 'toFixed' does not exist on type 'string'.

Exemplul 3: Union de valori literale

type Stare = "nouă" | "trimisă" | "livrată";

const comenzi: { id: number; stare: Stare }[] = [
    { id: 101, stare: "livrată" },
    { id: 102, stare: "nouă" },
    { id: 103, stare: "trimisă" },
];

for (const c of comenzi) {
    const gata = c.stare === "livrată" ? "✓" : "…";
    console.log(`#${c.id} ${c.stare.padEnd(8)} ${gata}`);
}

Rezultat

#101 livrată  ✓
#102 nouă     …
#103 trimisă  …

Greșeli frecvente

  • Faci as number ca să scapi de union. Dacă valoarea este de fapt text, eroarea apare la rulare; verifică tipul.
  • Scrii string | number[] și te aștepți la tablou mixt. Este „text sau tablou de numere”; pentru tablou mixt scrie (string | number)[].

Comenzi înrudite

  • intersection (&): Combină mai multe tipuri într-unul: A & B are toate proprietățile lui A și toate proprietățile lui B.
  • narrowing: TypeScript urmărește verificările din cod (if, switch, return) și restrânge tipul unei variabile în fiecare ramură.
  • discriminated unions: Un union de obiecte cu o proprietate comună de tip literal; verificarea ei arată exact ce variantă ai.
  • tipuri literale: Un tip care acceptă o singură valoare exactă, de exemplu „Iași” sau 3; combinate în union dau liste de valori permise.
  • Exclude: Exclude<T, U> elimină din union-ul T variantele care se potrivesc cu U.