microsoft / microsoft/TypeScript

Compilation option: `stricterPropertyInitialization`

Aperta
#60,906 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Awaiting More Feedback Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

🔍 Search Terms

Keywords: "stricter property initiazliation"

✅ Viability Checklist
⭐ Suggestion

So, TypeScript offers the strictPropertyInitialization compiler option, which is helpful, but it has this behavior:

class UserAccount {
  name: string; // not an error, initialized in constructor
  accountType = "user"; // initialized
 
  email: string; // this is an error
  address: string | undefined; // NOT an error but ALSO not technically initialized!
 
  constructor(name: string) {
    this.name = name;
  }
}

This is great except for one thing: performance. Uninitialized properties in the class (specifically: address) will, at least in V8, potentially switch the class to dictionary mode vs struct mode when the property eventually gets assigned, leading to slower read/writes. This was confirmed by a V8 developer in this StackOverflow thread.

So the suggestion is that stricterPropertyInitialization sets strictPropertyInitialization to true AND throws an error if the author has added | undefined to the type to implicity define the type. In other words, "strict property initialization" would mean what it says: strict property initialization. If it is not initialized, it is an error. In the above example, from the tsconfig docs, the address is not initialized. It's too late to change that as default behavior, hence the additional flag.

Note: maybe stricterPropertyInitialization is too awkward? Something like disallowImplicitUndefinedClassFields? 🤷‍♂

📃 Motivating Example

Most devs probably won't need to worry about the performance implications of internal dictionary vs. struct. In my case, in the library I'm maintaining / working on, every millisecond / fraction of a millisecond counts, so I'm trying to determine the fastest path in every scenario. I expected strictPropertyInitialization to mean what it says to prevent properties from not being initialized and avoid any accidental performance pitfalls from non-initialization, but it doesn't. 🤷‍♂

Meaning, in the above example:

class UserAccount {
  name: string; // not an error, initialized in constructor
  accountType = "user"; // initialized
 
  email: string; // this is an error
  address: string | undefined; // NOT an error but ALSO not technically initialized!
 
  constructor(name: string) {
    this.name = name;
  }

  someMethod() {
    // The class will now possible de-optimize its performance to Dictionary mode, since V8
    // thinks that the object needs to have arbitrary properties added. It doesn't know about `address`
    this.address = '123 fake street' 
  }
}

So, most simply, stricterPropertyInitialization would throw a compilation error if | undefined is added to a property and the property is not explicitly initialized with a field initializer or in the constructor.

If the code author wishes to actually initialize the field, to undefined, it must be something like:

class UserAccount {
  // ...
  address: string | undefined = undefined;
 
  constructor(name: string) {
    this.name = name;
  }
}
💻 Use Cases
  1. What do you want to use this for?
    A high-performance TS/JS library

  2. What shortcomings exist with current approaches?
    There are no workarounds as far as I know. You simply have to let all devs on your team know to not write this and hope people catch it.

  3. What workarounds are you using in the meantime?
    Vigilance

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

L’issue non indica file, test o punti di ingresso. Inizia individuando l’implementazione e i test per strictPropertyInitialization, quindi determina come un’opzione separata debba trattare i campi non inizializzati tipizzati con | undefined rispetto ai campi inizializzati esplicitamente. Il lavoro è completato quando il comportamento e il nome della nuova opzione sono definiti e gli esempi UserAccount sono coperti da compiler test.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.