microsoft / microsoft/TypeScript
Assertion methods (`asserts this is`) are not CFA'd without error
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
TypeScript Version: 4.0.5, 4.1.0-beta, 4.2.0-dev.20201112
Search Terms:
- Multiple assertion methods
- "asserts this is"
- assertion "cfa"
Code
class X<T, Locked extends boolean> {
public x: null | T | (Locked extends true ? 1 : 2) = null
public assert<U>(): asserts this is X<U, Locked> { }
public lock(): asserts this is X<T, true> {}
}
const x: X<string | number, false> = new X<string | number, false>()
x.assert<string>()
// x is X<string, false> here
x.lock()
Expected behavior:
Either:
- After
x.lock(),xis narrowed toX<string, true> - Or, the
x.lock()line throws at compile-time due to not being CFA'd
Actual behavior:
After x.lock(), x is narrowed to X<string, false> & X<string | number, true>.
Analysis:
x being typed as X<string, false> & X<string | number, true> shows that the x.lock() narrows from the original type (X<string | number, false>) instead of the narrowed type at that position (X<string, false>).
If instead a "top-level" assertion function is used the type is properly narrowed:
class X<T, Locked extends boolean> {
public x: null | T | (Locked extends true ? 1 : 2) = null
public assert<U>(): asserts this is X<U, Locked> { }
public lock(): asserts this is X<T, true> {}
}
const x: X<string | number, false> = new X<string | number, false>()
x.assert<string>()
// x is X<string, false> here
declare function lock<T>(v: X<T, boolean>): asserts v is X<T, true>
lock(x)
This leads me to believe this is an issue with the x.lock() call not being CFA'd, in which case the correct behavior would be to throw ts(2775) on the x.lock() line.
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
Führen Sie zunächst die bereitgestellte TypeScript Playground-Reproduktion aus und vergleichen Sie die Kontrollfluss-Narrowing nach x.assert<string>() und x.lock(). Untersuchen Sie die Behandlung von Methoden mit asserts this is durch den Compiler sowie den gemeldeten Intersection-Typ. Als erledigt gilt die Aufgabe, wenn die zweite Assertion entweder auf X<string, true> eingrenzt oder den erwarteten Compile-Time-Fehler meldet und eine Regressionstestabdeckung für das Beispiel vorhanden ist.
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
- 35/100