Partial în TypeScript

Partial<T> face toate proprietățile lui T opționale; util pentru actualizări în care trimiți doar ce se schimbă.

Sintaxă
type Partial<T> = { [P in keyof T]?: T[P] };

Ce face Partial

Partial<T> creează un tip cu aceleași proprietăți ca T, dar toate opționale (cu ?). Un Partial<Elev> poate avea doar nume, doar nota, ambele sau niciuna. Proprietățile care există trebuie totuși să aibă tipul corect.

Cel mai des îl folosești la funcții de actualizare (actualizeaza(id, { nota: 10 })), la opțiuni cu valori implicite ({ ...implicite, ...optiuni }) și la obiecte construite pas cu pas. Este superficial: proprietățile obiectelor imbricate rămân obligatorii în interiorul lor.

Este definit ca un mapped type. Opusul lui este Required. Cu opțiunea exactOptionalPropertyTypes, o proprietate opțională nu mai acceptă valoarea undefined scrisă explicit, doar lipsa ei.

Parametri

Parametru Descriere
T Tipul obiect ale cărui proprietăți devin opționale.

Ce returnează

Un tip obiect cu aceleași chei ca T, toate opționale.

Exemple

Exemplul 1: Actualizare cu doar câteva câmpuri

interface Elev {
    id: number;
    nume: string;
    oras: string;
    nota: number;
}

function actualizeaza(elev: Elev, schimbari: Partial<Elev>): Elev {
    return { ...elev, ...schimbari };
}

const ana: Elev = { id: 1, nume: "Ana", oras: "Iași", nota: 9 };
console.log(actualizeaza(ana, { nota: 10 }));
console.log(actualizeaza(ana, { oras: "Cluj", nota: 8 }));

Rezultat

{ id: 1, nume: 'Ana', oras: 'Iași', nota: 10 }
{ id: 1, nume: 'Ana', oras: 'Cluj', nota: 8 }

Exemplul 2: Opțiuni cu valori implicite

interface Optiuni {
    moneda: string;
    zecimale: number;
    separator: string;
}
const IMPLICITE: Optiuni = { moneda: "lei", zecimale: 2, separator: "," };

function pret(suma: number, optiuni: Partial<Optiuni> = {}): string {
    const o = { ...IMPLICITE, ...optiuni };
    return `${suma.toFixed(o.zecimale).replace(".", o.separator)} ${o.moneda}`;
}

console.log(pret(12.5));
console.log(pret(12.5, { moneda: "euro", separator: "." }));
console.log(pret(12.5, { zecimale: 0 }));

Rezultat

12,50 lei
12.50 euro
13 lei

Exemplul 3: Tipul proprietăților se verifică în continuare

interface Elev {
    nume: string;
    nota: number;
}
const s: Partial<Elev> = { nota: "zece" };
console.log(s);

Eroarea afișată de tsc

exemplu.mts(5,28): error TS2322: Type 'string' is not assignable to type 'number'.

Greșeli frecvente

  • Folosești Partial<T> ca tip pentru un obiect complet. Toate proprietățile devin T | undefined la citire și trebuie verificate peste tot.
  • Te aștepți ca Partial să facă opționale și proprietățile imbricate. Este superficial; pentru adâncime ai nevoie de un tip recursiv propriu.

Comenzi înrudite

  • Required: Required<T> face toate proprietățile lui T obligatorii, inclusiv pe cele marcate cu ?.
  • Readonly: Readonly<T> face toate proprietățile lui T readonly: obiectul poate fi citit, dar nu modificat.
  • Pick: Pick<T, K> păstrează din T doar proprietățile cu numele din K.
  • Omit: Omit<T, K> creează un tip cu toate proprietățile lui T, mai puțin cele cu numele din K.
  • mapped types: Construiesc un tip nou trecând prin fiecare cheie a altui tip: { [K in keyof T]: … }.