tipuri literale în TypeScript

Tipuri de bază TypeScript 2.0

Un tip care acceptă o singură valoare exactă, de exemplu "Iași" sau 3; combinate în union dau liste de valori permise.

Sintaxă
type Directie = "sus" | "jos";
type Zar = 1 | 2 | 3 | 4 | 5 | 6;
let activ: true = true;

Ce face tipuri literale

Un tip literal este o valoare concretă folosită ca tip: "admin", 42, true. O variabilă cu tipul "admin" poate avea doar valoarea "admin". Singure nu sunt foarte utile, dar combinate cu union descriu exact ce valori sunt permise: "mic" | "mediu" | "mare".

Este o alternativă simplă la enum: editorul îți propune valorile, iar o greșeală de scriere ("medu") este eroare de compilare. Valorile literale stau la baza discriminated unions și a template literal types.

TypeScript deduce tipuri literale pentru const cu valori simple. Pentru proprietățile obiectelor deduce tipul general (string), pentru că acestea se pot schimba; ca să păstrezi valorile exacte, folosește as const.

Exemple

Exemplul 1: Listă de valori permise

type Marime = "mic" | "mediu" | "mare";

const preturi: Record<Marime, number> = { mic: 8, mediu: 11, mare: 14 };

function comanda(produs: string, marime: Marime): string {
    return `${produs} (${marime}): ${preturi[marime]} lei`;
}

console.log(comanda("cafea", "mediu"));
console.log(comanda("ceai", "mare"));

Rezultat

cafea (mediu): 11 lei
ceai (mare): 14 lei

Exemplul 2: Valoare care nu este în listă

type Marime = "mic" | "mediu" | "mare";
function comanda(marime: Marime) {
    console.log(marime);
}
comanda("medu");

Eroarea afișată de tsc

exemplu.mts(5,9): error TS2345: Argument of type '"medu"' is not assignable to parameter of type 'Marime'.

Exemplul 3: Literale numerice

Tipul Zar are șase valori. Rezultatul calculului este number, deci trebuie verificat înainte să fie folosit ca Zar.

type Zar = 1 | 2 | 3 | 4 | 5 | 6;

function esteZar(n: number): n is Zar {
    return Number.isInteger(n) && n >= 1 && n <= 6;
}

function muta(pozitie: number, zar: Zar): number {
    return pozitie + zar;
}

for (const n of [3, 7]) {
    if (esteZar(n)) console.log(`zar ${n}: ajungi la ${muta(10, n)}`);
    else console.log(`${n} nu este o valoare de zar`);
}

Rezultat

zar 3: ajungi la 13
7 nu este o valoare de zar

Greșeli frecvente

  • Pui un obiect cu proprietăți literale într-o variabilă fără tip și îl dai unei funcții care cere tipul literal: proprietatea a devenit string. Pune tipul pe variabilă sau folosește as const.
  • Repeți aceeași listă de valori în mai multe locuri. Pune-o într-un type și refolosește-o.

Comenzi înrudite

  • union (|): Un tip care acceptă valori din mai multe tipuri: A | B înseamnă fie A, fie B.
  • as const: Face un literal complet readonly și păstrează valorile exacte ca tipuri: „Iași” în loc de string.
  • enum: Un set de constante cu nume, numerice sau text, care există și la rulare ca obiect.
  • discriminated unions: Un union de obiecte cu o proprietate comună de tip literal; verificarea ei arată exact ce variantă ai.
  • template literal types: Tipuri de text construite ca un template string: `id-${number}` acceptă „id-1”, „id-42” și așa mai departe.