microsoft / microsoft/TypeScript

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

Aperta
#21,985 3 commenti 28 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

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:

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 riproducendo il codice TypeScript dell'issue con strictNullChecks abilitato e confronta i casi if e switch. Traccia il narrowing del control-flow del compilatore e l'analisi dei ritorni mancanti per la funzione errata. Il lavoro è completo quando la diagnostica segnalata è risolta per questo caso e la copertura di regressione conferma il comportamento.

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

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.