Extract în TypeScript

Extract<T, U> păstrează din union-ul T doar variantele care se potrivesc cu U.

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

Ce face Extract

Extract este opusul lui Exclude: păstrează doar variantele din T atribuibile lui U. Extract<string | number | boolean, number | boolean> dă number | boolean.

Este foarte util la discriminated unions: Extract<Eveniment, { tip: "click" }> scoate exact varianta cu tip: "click", cu toate proprietățile ei. Așa poți scrie funcții care tratează o singură variantă, fără să repeți tipul.

Ca intersecție a două union-uri de literale, Extract<A, B> dă valorile comune.

Parametri

Parametru Descriere
T Union-ul de pornire.
U Tipul cu care trebuie să se potrivească variantele păstrate.

Ce returnează

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

Exemple

Exemplul 1: O variantă dintr-un discriminated union

type Actiune =
    | { tip: "adauga"; produs: string; cantitate: number }
    | { tip: "sterge"; produs: string }
    | { tip: "goleste" };

type Adaugare = Extract<Actiune, { tip: "adauga" }>;

function format(a: Adaugare): string {
    return `+${a.cantitate} × ${a.produs}`;
}

const actiuni: Actiune[] = [
    { tip: "adauga", produs: "mere", cantitate: 2 },
    { tip: "sterge", produs: "pere" },
    { tip: "adauga", produs: "pâine", cantitate: 1 },
];
const adaugari = actiuni.filter((a): a is Adaugare => a.tip === "adauga");
console.log(adaugari.map(format));

Rezultat

[ '+2 × mere', '+1 × pâine' ]

Exemplul 2: Valori comune a două liste

type LaIasi = "informatică" | "matematică" | "fizică";
type LaCluj = "informatică" | "chimie" | "fizică";
type Comune = Extract<LaIasi, LaCluj>;          // "informatică" | "fizică"

const materii: Comune[] = ["informatică", "fizică"];
console.log(materii);

Rezultat

[ 'informatică', 'fizică' ]

Exemplul 3: Valoare care nu este în ambele

type A = "a" | "b" | "c";
type B = "b" | "c" | "d";
const x: Extract<A, B> = "a";
console.log(x);

Eroarea afișată de tsc

exemplu.mts(3,7): error TS2322: Type '"a"' is not assignable to type '"b" | "c"'.

Greșeli frecvente

  • Confunzi Extract cu Pick. Extract alege variante dintr-un union; Pick alege proprietăți dintr-un obiect.

Comenzi înrudite

  • Exclude: Exclude<T, U> elimină din union-ul T variantele care se potrivesc cu U.
  • discriminated unions: Un union de obiecte cu o proprietate comună de tip literal; verificarea ei arată exact ce variantă ai.
  • conditional types: Un tip care alege între două variante după o condiție: T extends U ? X : Y.
  • Pick: Pick<T, K> păstrează din T doar proprietățile cu numele din K.