as const în TypeScript

Face un literal complet readonly și păstrează valorile exacte ca tipuri: "Iași" în loc de string.

Sintaxă
const x = { a: 1, b: "text" } as const;
const lista = ["a", "b"] as const;

Ce face as const

as const pus după un obiect sau un tablou literal spune: „valoarea aceasta nu se va schimba”. TypeScript face trei lucruri: toate proprietățile devin readonly (la orice adâncime), tablourile devin tuple-uri readonly, iar valorile își păstrează tipul literal ("Iași", 200) în loc de tipul general (string, number).

Este felul obișnuit de a defini constante din care derivi tipuri: o listă de orașe din care faci un union cu (typeof ORASE)[number], un obiect de coduri din care faci un union cu (typeof CODURI)[keyof typeof CODURI]. Este o alternativă la enum care nu generează cod special.

Ca orice aserțiune de tip, as const lucrează doar la compilare; la rulare obiectul se poate modifica în continuare (pentru asta există Object.freeze). Se poate pune doar pe literale, nu pe variabile sau rezultate de funcții. Combinat cu satisfies ({...} as const satisfies Tip) obții și verificare, și valori exacte.

Exemple

Exemplul 1: Listă de valori și union derivat din ea

const MATERII = ["matematică", "informatică", "fizică"] as const;
type Materie = (typeof MATERII)[number];   // "matematică" | "informatică" | "fizică"

const note: Record<Materie, number> = { "matematică": 9, "informatică": 10, "fizică": 8 };

for (const m of MATERII) {
    console.log(m.padEnd(12), note[m]);
}

Rezultat

matematică   9
informatică  10
fizică       8

Exemplul 2: Cu și fără as const

Fără as const, metoda are tipul string și nu poate fi dată funcției care acceptă doar "GET" | "POST".

function cerere(url: string, metoda: "GET" | "POST"): string {
    return `${metoda} ${url}`;
}

const c1 = { url: "/api/elevi", metoda: "GET" } as const;
console.log(cerere(c1.url, c1.metoda));

const c2 = { url: "/api/note", metoda: "POST" };
console.log(cerere(c2.url, c2.metoda));

Eroarea afișată de tsc

exemplu.mts(9,28): error TS2345: Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.

Exemplul 3: Totul devine readonly

const SETARI = { limba: "ro", orase: ["Iași", "Cluj"] } as const;
SETARI.limba = "en";
SETARI.orase.push("Brașov");

Eroarea afișată de tsc

exemplu.mts(2,8): error TS2540: Cannot assign to 'limba' because it is a read-only property.
exemplu.mts(3,14): error TS2339: Property 'push' does not exist on type 'readonly ["Iași", "Cluj"]'.

Greșeli frecvente

  • Pui as const pe o variabilă: x as const. tsc dă A ‘const’ assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.
  • Te aștepți ca as const să blocheze modificările la rulare. Pentru asta folosește Object.freeze.

Comenzi înrudite

  • satisfies: Verifică dacă o valoare se potrivește cu un tip, dar păstrează tipul ei exact, mai precis decât Tip.
  • tipuri literale: Un tip care acceptă o singură valoare exactă, de exemplu „Iași” sau 3; combinate în union dau liste de valori permise.
  • readonly: Marchează o proprietate care primește valoare o singură dată și nu mai poate fi modificată după aceea.
  • typeof (tip): În poziție de tip, typeof x dă tipul variabilei sau funcției x, ca să nu-l scrii de mână.
  • enum: Un set de constante cu nume, numerice sau text, care există și la rulare ca obiect.