Ce face useDefineForClassFields
Înainte ca JavaScript să aibă câmpuri de clasă, TypeScript le transforma în atribuiri în constructor: this.nume = "necunoscut". Standardul final a ales altă regulă: câmpurile sunt definite (ca Object.defineProperty), chiar și cele fără valoare, care primesc undefined. Diferența se vede la moștenire: un câmp redeclarat în clasa copil suprascrie valoarea pusă de constructorul părintelui.
Cu useDefineForClassFields, TypeScript urmează standardul. Implicit este true pentru target es2022 sau mai nou (inclusiv esnext) și false altfel. Codul vechi care depinde de comportamentul vechi poate avea nevoie de false; pentru un câmp doar redeclarat ca tip, scrie declare pret?: number, care nu generează nimic.
Parametri
| Parametru | Descriere |
|---|---|
true |
Semantica standard (define). Implicit de la target: es2022. |
false |
Semantica veche (atribuire în constructor). |
Exemple
Exemplul 1: Un câmp suprascris după constructorul părintelui
Baza apelează init(), care pune pret = 10. Cu semantica standard, câmpul pret? din Produs este definit după constructorul părintelui și revine la undefined. Cu --useDefineForClassFields false, valoarea 10 rămâne.
// tsconfig.json
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext"
}
}
// index.ts
class Baza {
constructor() {
this.init();
}
init() {}
}
class Produs extends Baza {
nume = "necunoscut";
pret?: number;
override init() {
this.pret = 10;
}
}
const p = new Produs();
console.log(p, Object.keys(p));
Rezultat (tsc 5.9)
$ npx tsc && node index.js
Produs { pret: undefined, nume: 'necunoscut' } [ 'pret', 'nume' ]
$ npx tsc --useDefineForClassFields false && node index.js
Produs { pret: 10, nume: 'necunoscut' } [ 'pret', 'nume' ]
Exemplul 2: Rezolvarea cu declare
declare pret?: number spune doar tipul, fără să genereze un câmp. Valoarea pusă de init() rămâne și cu semantica standard (folosită de exemplele site-ului).
class Baza {
constructor() {
this.init();
}
init(): void {}
}
class Produs extends Baza {
nume = "necunoscut";
declare pret?: number;
override init(): void {
this.pret = 10;
}
}
const p = new Produs();
console.log(p.pret, p.nume);
Rezultat
10 necunoscut
Greșeli frecvente
- Să schimbi
targetde laes2020laes2022fără să verifici clasele care redeclară câmpuri. Implicitul luiuseDefineForClassFieldsse schimbă odată cu ținta.
Comenzi înrudite
target: Versiunea de JavaScript generată: sintaxa mai nouă decât ținta este transformată în cod echivalent mai vechi.strictPropertyInitialization: Dă eroare pentru proprietățile de clasă declarate, dar care nu primesc valoare nici la declarare, nici în constructor.experimentalDecorators: Activează decoratorii vechi (experimentali) ai lui TypeScript, folosiți de Angular și NestJS, în locul celor standard.