microsoft / microsoft/TypeScript

narrowing to "never" by "if" statement does not exclude "undefined" return type

Offen
#21,985 3 Kommentare 28 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

In Discussion Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

TypeScript Version: 2.7.1

Search Terms: narrowing types never switch case if undefined strictNullChecks

Code

// Build this code with "--strictNullChecks" option.

function assertNever(x: never): never {
    throw new Error("not reached");
}

enum A {
    Foo, Bar
}

// There are no errors on this function.
function good(a: A): number {
    switch (a) {
        case A.Foo: return 0;
        case A.Bar: return 1;
    }
}

// This function causes the following error though "a" is "never" at the end of the function.
// error TS2366: Function lacks ending return statement and return type does not include 'undefined'.
function bad(a: A): number {
    if (a === A.Foo) return 0;
    if (a === A.Bar) return 1;
}

// No error if explicit return of "never" is added.
function ok(a: A): number {
    if (a === A.Foo) return 0;
    if (a === A.Bar) return 1;
    return assertNever(a);
}

Expected behavior: The bad() function should not cause error so that if statement works like switch.

Actual behavior: As commented in the code, only bad() function causes an error.

Playground Link: (please check "strictNullChecks" option.)

http://www.typescriptlang.org/play/#src=function%20assertNever(x%3A%20never)%3A%20never%20%7B%0D%0A%20%20%20%20throw%20new%20Error(%22unexpected%22)%3B%0D%0A%7D%0D%0A%0D%0Aenum%20A%20%7B%0D%0A%20%20%20%20Foo%2C%20Bar%0D%0A%7D%0D%0A%0D%0Afunction%20good(a%3A%20A)%3A%20number%20%7B%0D%0A%20%20%20%20switch%20(a)%20%7B%0D%0A%20%20%20%20%20%20%20%20case%20A.Foo%3A%20return%200%3B%0D%0A%20%20%20%20%20%20%20%20case%20A.Bar%3A%20return%201%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20bad(a%3A%20A)%3A%20number%20%7B%0D%0A%20%20%20%20if%20(a%20%3D%3D%3D%20A.Foo)%20return%200%3B%0D%0A%20%20%20%20if%20(a%20%3D%3D%3D%20A.Bar)%20return%201%3B%0D%0A%7D%0D%0A%0D%0Afunction%20ok(a%3A%20A)%3A%20number%20%7B%0D%0A%20%20%20%20if%20(a%20%3D%3D%3D%20A.Foo)%20return%200%3B%0D%0A%20%20%20%20if%20(a%20%3D%3D%3D%20A.Bar)%20return%201%3B%0D%0A%20%20%20%20return%20assertNever(a)%3B%0D%0A%7D

Related Issues:

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

Beginne damit, den TypeScript-Code des Issues mit aktiviertem strictNullChecks zu reproduzieren, und vergleiche die if- und switch-Fälle. Verfolge die Control-Flow-Narrowing- und Missing-Return-Analyse des Compilers für die fehlerhafte Funktion. Als erledigt gilt die Aufgabe, wenn die gemeldete Diagnose für diesen Fall behoben ist und die Regression-Abdeckung das Verhalten bestätigt.

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
Klar beschrieben
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

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