Exclude în TypeScript

Exclude<T, U> elimină din union-ul T variantele care se potrivesc cu U.

Sintaxă
type Exclude<T, U> = T extends U ? never : T;

Ce face Exclude

Exclude<"a" | "b" | "c", "a"> dă "b" | "c". Fiecare variantă din T care se potrivește cu U (este atribuibilă lui U) dispare. U poate fi și un tip general: Exclude<string | number | boolean, string> dă number | boolean.

Lucrează pe union-uri de tipuri, nu pe obiecte. Pentru a elimina proprietăți dintr-un obiect folosește Omit (care folosește intern Exclude pe keyof T). Opusul lui este Extract.

Este un tip condițional distributiv: condiția se aplică pe fiecare variantă a union-ului, iar never înseamnă „elimină varianta”.

Parametri

Parametru Descriere
T Union-ul de pornire.
U Tipul (sau union-ul) variantelor eliminate.

Ce returnează

Union-ul variantelor din T care nu se potrivesc cu U.

Exemple

Exemplul 1: Stări fără cea finală

type Stare = "nouă" | "trimisă" | "livrată" | "anulată";
type Activa = Exclude<Stare, "livrată" | "anulată">;     // "nouă" | "trimisă"

function poateFiModificata(s: Stare): s is Activa {
    return s === "nouă" || s === "trimisă";
}

for (const s of ["nouă", "livrată", "trimisă"] as Stare[]) {
    console.log(s.padEnd(8), poateFiModificata(s) ? "se poate modifica" : "închisă");
}

Rezultat

nouă     se poate modifica
livrată  închisă
trimisă  se poate modifica

Exemplul 2: Eliminarea unui tip întreg

Din variantele unui eveniment se elimină toate obiectele care au tip: "tick".

type Eveniment =
    | { tip: "click"; x: number; y: number }
    | { tip: "tasta"; cod: string }
    | { tip: "tick" };

type Interactiune = Exclude<Eveniment, { tip: "tick" }>;

function descrie(e: Interactiune): string {
    return e.tip === "click" ? `click la ${e.x},${e.y}` : `tasta ${e.cod}`;
}

console.log(descrie({ tip: "click", x: 10, y: 20 }), "|", descrie({ tip: "tasta", cod: "Enter" }));

Rezultat

click la 10,20 | tasta Enter

Exemplul 3: Valoarea eliminată nu mai este acceptată

type Stare = "nouă" | "trimisă" | "livrată";
const s: Exclude<Stare, "livrată"> = "livrată";
console.log(s);

Eroarea afișată de tsc

exemplu.mts(2,7): error TS2322: Type '"livrată"' is not assignable to type '"nouă" | "trimisă"'.

Greșeli frecvente

  • Folosești Exclude pe un tip obiect ca să scoți o proprietate. Nu are efect; folosește Omit.

Comenzi înrudite

  • Extract: Extract<T, U> păstrează din union-ul T doar variantele care se potrivesc cu U.
  • Omit: Omit<T, K> creează un tip cu toate proprietățile lui T, mai puțin cele cu numele din K.
  • NonNullable: NonNullable<T> elimină null și undefined din tipul T.
  • conditional types: Un tip care alege între două variante după o condiție: T extends U ? X : Y.
  • union (|): Un tip care acceptă valori din mai multe tipuri: A | B înseamnă fie A, fie B.