Record în TypeScript

Record<K, T> descrie un obiect ale cărui chei sunt K și ale cărui valori au toate tipul T.

Sintaxă
type Record<K extends keyof any, T> = { [P in K]: T };

Ce face Record

Record<K, T> este un obiect cu cheile K și valorile de tip T. Când K este un union de literale, Record<"lei" | "euro", number>, obiectul trebuie să aibă exact aceste chei: dacă lipsește una, este eroare. Așa te asiguri că un tabel de traduceri, prețuri sau culori acoperă toate cazurile.

Cu K = string, Record<string, number> este un dicționar cu chei oarecare, echivalent cu { [cheie: string]: number } (vezi index signatures). În acest caz, citirea unei chei care nu există are tipul number, nu number | undefined, dacă nu ai activat noUncheckedIndexedAccess.

Pentru dicționare în care adaugi și ștergi des chei, Map<K, V> este de obicei mai potrivit. Partial<Record<K, T>> face toate cheile opționale.

Parametri

Parametru Descriere
K Tipul cheilor: string, number, symbol sau un union de literale.
T Tipul tuturor valorilor.

Ce returnează

Un tip obiect cu cheile K și valori de tipul T.

Exemple

Exemplul 1: Toate cheile unui union trebuie să existe

type Zi = "luni" | "marți" | "miercuri" | "joi" | "vineri";

const ore: Record<Zi, number> = { luni: 6, "marți": 7, miercuri: 6, joi: 5, vineri: 4 };
const total = Object.values(ore).reduce((s, n) => s + n, 0);
console.log(ore, "total:", total);

Rezultat

{ luni: 6, 'marți': 7, miercuri: 6, joi: 5, vineri: 4 } total: 28

Exemplul 2: Gruparea unei liste într-un dicționar

interface Elev {
    nume: string;
    oras: string;
}
const elevi: Elev[] = [
    { nume: "Ana", oras: "Iași" },
    { nume: "Mihai", oras: "Cluj" },
    { nume: "Ioana", oras: "Iași" },
];

const peOrase: Record<string, string[]> = {};
for (const e of elevi) {
    (peOrase[e.oras] ??= []).push(e.nume);
}
console.log(peOrase);

Rezultat

{ 'Iași': [ 'Ana', 'Ioana' ], Cluj: [ 'Mihai' ] }

Exemplul 3: Cheie lipsă

type Moneda = "lei" | "euro" | "dolari";
const curs: Record<Moneda, number> = { lei: 1, euro: 4.97 };
console.log(curs);

Eroarea afișată de tsc

exemplu.mts(2,7): error TS2741: Property 'dolari' is missing in type '{ lei: number; euro: number; }' but required in type 'Record<Moneda, number>'.

Greșeli frecvente

  • Folosești Record<string, T> când cheile sunt de fapt cunoscute. Un union de literale prinde cheile lipsă și greșelile de scriere.
  • Crezi că Record<string, number> garantează că orice cheie există. Valoarea citită poate fi undefined la rulare.

Comenzi înrudite

  • index signatures: Descrie obiecte cu chei necunoscute dinainte: [cheie: string]: Tip, sau Record<string, Tip>.
  • Partial: Partial<T> face toate proprietățile lui T opționale; util pentru actualizări în care trimiți doar ce se schimbă.
  • Pick: Pick<T, K> păstrează din T doar proprietățile cu numele din K.
  • mapped types: Construiesc un tip nou trecând prin fiecare cheie a altui tip: { [K in keyof T]: … }.
  • keyof: keyof T dă union-ul numelor de proprietăți ale lui T, de exemplu „nume” | „oras”.