microsoft / microsoft/TypeScript

Type narrowing on object properties lost in async IIFE

Offen
#30,625 2 Kommentare 4 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Experience Enhancement Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

TypeScript Version: 3.4.0-dev.20190327

Search Terms:
narrowing iife control flow

Code

declare const x: string | undefined;
declare const y: { z: string | undefined };
function needsString(it: string) { return it; }

function a() {
  if (!x) {
    throw new Error("Missing x");
  }
  const res1 = (() => needsString(x))(); // all good, per #8849
  const res2 = (async () => needsString(x))();  // ditto

  if (!y.z) {
    throw new Error("Missing z.")
  }

  const res3 = (() => needsString(y.z))();  // still good
  const res4 = (async () => needsString(y.z))();  // now things blow up  
}

Expected behavior:
The call to needsString in the expression for res4 succeeds, like the one in res2 and res3. Even though the function is async, the code in it -- at least that's before an await -- runs immediately, I believe, and so should be subject to the narrowing (esp. given that res2 works).

Actual behavior:
Error for needsString(y.z): Argument of type 'string | undefined' is not assignable to parameter of type 'string'.

Playground Link: https://www.typescriptlang.org/play/index.html#src=declare%20const%20x%3A%20string%20%7C%20undefined%3B%0Adeclare%20const%20y%3A%20%7B%20z%3A%20string%20%7C%20undefined%20%7D%3B%0Afunction%20needsString(it%3A%20string)%20%7B%20return%20it%3B%20%7D%0A%0Afunction%20a()%20%7B%0A%20%20if%20(!x)%20%7B%0A%20%20%20%20throw%20new%20Error(%22Missing%20x%22)%3B%0A%20%20%7D%0A%20%20const%20res1%20%3D%20(()%20%3D%3E%20needsString(x))()%3B%20%2F%2F%20all%20good%2C%20per%20%238849%0A%20%20const%20res2%20%3D%20(async%20()%20%3D%3E%20needsString(x))()%3B%20%20%2F%2F%20ditto%0A%0A%20%20if%20(!y.z)%20%7B%0A%20%20%20%20throw%20new%20Error(%22Missing%20z.%22)%0A%20%20%7D%0A%0A%20%20const%20res3%20%3D%20(()%20%3D%3E%20needsString(y.z))()%3B%20%20%2F%2F%20still%20good%0A%20%20const%20res4%20%3D%20(async%20()%20%3D%3E%20needsString(y.z))()%3B%20%20%2F%2F%20now%20things%20blow%20up%20%20%0A%7D

Related Issues:
https://github.com/Microsoft/TypeScript/pull/8849, which I think was supposed to fix IIFE issues like this, but appears to have missed a case (or I'm missing something).

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere das Beispiel aus dem Issue im verlinkten TypeScript Playground mit der gemeldeten Version 3.4.0-dev und vergleiche die Narrowing-Fälle x und y.z rund um die async IIFE. Verfolge das Control-Flow-Narrowing des Compilers für Objekteigenschaften und ergänze Tests, sodass der Aufruf res4 y.z als string akzeptiert, ohne das bestehende Verhalten von res2 und res3 zu ändern.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.