microsoft / microsoft/TypeScript

This narrowing typeguard effect bleeds into subsequent statments on a type with bivariant type-parameter

Offen
#30,461 10 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Needs Proposal 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.201xxxxx (although 3.3 is also impacted)
Search Terms: this type guards

If we create a type-guard that narrows this on a type that has a type-parameter that is present only in a bivariant position, the effect of the type guard persists outside of the guarded block.

Code

type GetKnownKeys<G> = G extends GuardedMap<infer KnownKeys>  ? KnownKeys: never;
interface GuardedMap<KnownKeys extends string> {
    get(k: KnownKeys): number;
    has<S extends string>(k: S): this is GuardedMap<S | GetKnownKeys<this>>;
}

declare let map: GuardedMap<never>;

map.get('bar') // err, as expected
if (map.has('foo')) {
    map.get('foo').toExponential(); // ok as expected
    if(map.has('bar')) 
    {
        map.get('foo').toExponential(); // ok as expected
        map.get('bar').toExponential(); // ok as expected
    }
        
    map.get('bar').toExponential(); /// OK!?!?! WHY ?!
    
}
map.get('bar') // OK ?!

Expected behavior:
Type guard only impacts the guarded block.
Actual behavior:
The effect of the type guard bleads into all subsequent statements. (marked with OK!?!?! and OK?!)

Note: With strictFunctionTypes on, declaring get as get: (k: KnownKeys) => number; makes the code work as expected.

Playground Link: link

Related Issues: Similar to #14817

Found this while playing with a solution for #9619

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 Narrowing-Leak im verknüpften TypeScript Playground mithilfe des bereitgestellten GuardedMap-Beispiels. Verfolge die Control-Flow-Behandlung des Compilers für this-Type-Guards und bivariante Typparameter; abgeschlossen ist die Aufgabe, wenn das Narrowing auf den bewachten Block beschränkt bleibt und map.get('bar') nach dem Block abgelehnt wird, einschließlich Regressionstests.

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
38/100

Neue Issues direkt in Ihr Postfach

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