microsoft / microsoft/TypeScript
Refinement type inference quirk with implicitly typed `let x`
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.4k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 117
Beschreibung
🔎 Search Terms
refinement narrow let any
🕗 Version & Regression Information
- This changed between versions 3.9.7 and 4.0.5; the behavior is present in every version from 4.0.5 to 5.3 nightly; I skimmed the whole FAQ document and didn't find anything relevant
⏯ Playground Link
💻 Code
type MyType = { type: 'A' } | { type: 'B' };
function f(arg: MyType) {
let x;
x = arg;
if (x.type === 'A') {
} else if (x.type === 'B') {
} else {
let _: never = x;
}
}
🙁 Actual behavior
error TS2322: Type '{ type: "B"; }' is not assignable to type 'never'.
9 let _: never = x;
~
This is wrong for two reasons:
- In the world of perfect type inference,
xshould be narrowed toneverat this point - Even acknowledging that there could be some practical limitations, the behavior is not consistent.
First conditional successfully eliminates the "A" variant:
But second conditional fails to eliminate the "B" variant:
🙂 Expected behavior
Ideally, this shouldn't be an error at all.
However, given that control-flow-based type inference has its limitations, perhaps some kind of spurious error is inevitable. In that case, it probably should be more like Type 'MyType' is not assignable to type 'never' rather than Type '{ type: "B" }' is not assignable to type 'never'.
Additional information about the issue
Practical impact of this issue is small. There is an easy workaround of adding an explicit type annotation (let x: MyType;).
However, this asymmetry, that the last conditional fails at narrowing when exactly the same conditional before that succeeds, bothers me. I'm reporting this because it could be a symptom of a more general implementation defect.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, das TypeScript Playground-Beispiel zu reproduzieren, und vergleiche das Verhalten zwischen den gemeldeten Versionen. Untersuche die auf dem Kontrollfluss basierende Typinferenz und -eingrenzung für ein implizit typisiertes let, das aus MyType zugewiesen wird; abgeschlossen ist die Untersuchung, wenn der abschließende else-Zweig konsistent eingegrenzt wird oder die vereinbarte Diagnose erzeugt, ohne die vorherige Eingrenzung zu beeinträchtigen.
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