microsoft / microsoft/TypeScript

Create flag strictVariableInitialization

Aperta
#60,064 5 commenti 2 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
1g 19h
PR unite (30g)
117

Descrizione

🔍 Search Terms

uninitialized variable, undefined, closure, strict property initialization,

✅ Viability Checklist
⭐ Suggestion

I would like to see a check that ensures that no variable whose type is not permitted to be undefined may remain uninitialized at the end of its scope.

📃 Motivating Example

TypeScript allows unsafety that can and does catch users by surprise when using variables in a closure. Normally, TS won't let you access an uninitialized variable:

function doSomething() {
   let foo: string;
   foo.toLowerCase(); // TS ERROR: Variable 'foo' is used before being assigned 
}

However, TypeScript optimistically assumes that variables are initialized when used in closures.

let foo: string;

function printFoo() {
    console.log(foo.toLowerCase());
}

printFoo(); // Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')

That's for good reason, but sometimes, as in the above case, this is provably unsafe, since foo is guaranteed not to be initialized.

The new flag "strictVariableInitialization" ensures that a variable must be initialized by the end of all reachable codepaths in its scope.

let foo: string; // (proposed) TS ERROR: `foo` is not initialized in all reachable codepaths 

function printFoo() {
    console.log(foo.toLowerCase());
}

printFoo()

Of course, variables whose type includes undefined are still permitted to be uninitialized.

let foo: string | undefined;

function printFoo() {
    console.log(foo?.toLowerCase());
}

printFoo();

This check is highly analogous to strictPropertyInitialization for classes.

💻 Use Cases

See https://github.com/typescript-eslint/typescript-eslint/issues/9565 for a somewhat-wordier proposal in typescript-eslint, and https://github.com/typescript-eslint/typescript-eslint/issues/4513 and https://github.com/typescript-eslint/typescript-eslint/issues/10055#issuecomment-2374797860 for cases where this has caused confusion in the wild.

In short, people who have written code that does check for initialization of non-nullable variables become confused by the linter informing them that the check is unnecessary according to the types, even though they can see that it is necessary at runtime:

let foo: Something

function useFoo() {
   if (foo != null) { // linter flags this condition as unnecessary since foo cannot be nullish
      foo.bar();
   }
}

The code should be rewritten as

let foo: Something | undefined

function useFoo() {
   if (foo != null) {
      foo.bar();
   }
}

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

Inizia esaminando il comportamento proposto di strictVariableInitialization e i relativi esempi di Closure motivanti, quindi confrontalo con strictPropertyInitialization. Definisci come devono essere gestiti i percorsi di codice raggiungibili e i tipi che includono undefined; il lavoro è concluso quando la proposta ha un design definito e un comportamento corrispondente del compilatore senza modificare il JavaScript emesso.

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

Valutazione

Stack tecnologico
javascript, typescript
Ambito
compilers
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.