erasableSyntaxOnly în TypeScript

Interzice construcțiile TypeScript care generează cod (enum, namespace, parametri-proprietate), ca Node.js să poată rula direct fișierele .ts.

Sintaxă
"compilerOptions": { "erasableSyntaxOnly": true }

Ce face erasableSyntaxOnly

Node.js (de la 23.6, fără steaguri) poate rula direct fișiere .ts: șterge tipurile și rulează ce rămâne. Funcționează doar pentru sintaxa „care se poate șterge” (tipuri, interfețe, as, satisfies). Construcțiile care produc cod JavaScript nou nu pot fi doar șterse: enum, namespace cu cod, parametrii-proprietate din constructor (constructor(public nume: string)), sintaxa import x = require().

Cu erasableSyntaxOnly, tsc dă eroarea TS1294 pentru aceste construcții. Așa afli la verificare, nu la rulare, că Node.js nu va putea rula fișierul. Alternative: un obiect as const în loc de enum, module în loc de namespace, câmpuri obișnuite în loc de parametri-proprietate.

Implicit: false. Se folosește de obicei împreună cu verbatimModuleSyntax și cu rewriteRelativeImportExtensions sau allowImportingTsExtensions.

Parametri

Parametru Descriere
true enum, namespace cu cod, parametrii-proprietate și import = dau eroare.
false Valoarea implicită.

Exemple

Exemplul 1: Trei construcții care generează cod

tsc semnalează toate trei. Node.js, rulând direct fișierul, se oprește la prima (mai jos, ieșirea lui Node.js este prescurtată).

// tsconfig.json
{
  "compilerOptions": {
    "erasableSyntaxOnly": true,
    "module": "nodenext",
    "noEmit": true
  }
}

// index.ts
enum Stare { Nou, Livrat }

namespace Magazin {
  export const nume = "La Ana";
}

class Client {
  constructor(public nume: string) {}
}

console.log(Stare.Nou, Magazin.nume, new Client("Ion").nume);

Rezultat (tsc 5.9)

$ npx tsc
index.ts(1,6): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.
index.ts(3,11): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.
index.ts(8,15): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.

$ node index.ts
file:///proiect/index.ts:1
enum Stare { Nou, Livrat }
^^^^^^^^^^^^^^^^^^^^^^^^^^

SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode

Exemplul 2: Aceleași idei, doar cu sintaxă care se poate șterge

Obiectul as const plus un tip înlocuiesc enum, iar câmpul este atribuit în constructor. Acest cod rulează și ca node index.ts.

const Stare = { Nou: 0, Livrat: 1 } as const;
type Stare = (typeof Stare)[keyof typeof Stare];

class Client {
  nume: string;
  constructor(nume: string) {
    this.nume = nume;
  }
}

const s: Stare = Stare.Livrat;
console.log(s, new Client("Ion").nume);
console.log(Object.keys(Stare));

Rezultat

1 Ion
[ 'Nou', 'Livrat' ]

Greșeli frecvente

  • Să crezi că opțiunea face tsc să ruleze codul. Doar verifică; rularea o face Node.js (sau altă unealtă).
  • Să folosești declare enum sau const enum din alte fișiere și să te aștepți că merg cu Node.js. Node.js nu citește alte fișiere ca să înlocuiască valorile.

Comenzi înrudite

  • verbatimModuleSyntax: Importurile rămân exact cum sunt scrise; se șterg doar cele marcate cu type, deci tipurile trebuie importate cu import type.
  • rewriteRelativeImportExtensions: Rescrie importurile relative care se termină în .ts, .mts, .cts în .js, .mjs, .cjs în fișierele generate.
  • allowImportingTsExtensions: Permite importuri cu extensia .ts („./calcul.ts”), când codul este rulat direct de Node.js, Deno, Bun sau de un bundler.
  • isolatedModules: Dă eroare pentru codul care nu poate fi transformat corect fișier cu fișier (de esbuild, Babel, swc sau Node.js).