microsoft / microsoft/TypeScript

Consider property access a form of type guards

Offen
#1,260 18 Kommentare 89 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Awaiting More Feedback Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

This is a proposal for using property access as another form of type guards (see #900) to narrow union types. While we're investigating expanding the power of type guards (#1007) this feature would support the natural style that JavaScript programmers have in their code today.

Using property access to narrow union types
var x: string|number;
if (x.length) { // no error even though number lacks a length property
    var r = x.charAt(3); // x is of type string inside this block
}

var r2 = x.length || x * x; // no error, x narrowed to number on right hand side, r3 is number

var y: string[]|number[]|string;
if (y.length && y.push) {
    // y is string[]|number[] now
    var first = y[0]; // first is string|number
    if (first.length) {
        // first is string in here
    } else {
        // first is number in here
    }
}

We do not expand the situations in which types are narrowed, but we do expand the known type guard patterns to include basic property access. In these narrowing contexts it would be an error to access a property that does not exist in at least one of the constituent types of a union type (as it is today). However, it would now be valid to access a property that exists in at least one, but not all, constituent types. Any such property access will then narrow the type of the operand to only those constituent types in the union which do contain the accessed property. In any other context property access is unchanged.

Invalid property access
var x: string|number;

var r = x.length; // error, not a type guard, normal property access rules apply

if (x.len) { } // error, len does not exist on type string|number 

var r3 = !x.len && x.length; // error, len does not exist on type string|number 

var r4 = x.length && x.len; // error, len does not exist on type string
Issues/Questions
  • Should the language service behave differently in these type guard contexts? Should dotting off a union type in a type guard list all members on all types rather than only those that exist on all of them?
  • Need to understand performance implications

I have a sample implementation and tests in a branch here: https://github.com/Microsoft/TypeScript/tree/typeGuardsViaPropertyAccess. There're a couple bugs remaining but examples like the above all work and no existing behavior was changed.

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 mit dem im Issue verlinkten Branch typeGuardsViaPropertyAccess und prüfe dessen Beispielimplementierung und Tests. Vergleiche die Beispiele und Fälle ungültiger Zugriffe in diesem Issue mit dem bestehenden Verhalten von Type Guards, das in #900 und #1007 besprochen wird. Als abgeschlossen gilt die Aufgabe, wenn die verbleibenden Bugs behoben, die Fragen zum Language Service und zur Performance geklärt sowie Tests für die vorgeschlagenen Narrowing-Regeln hinzugefügt oder aktualisiert wurden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
javascript, typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
20/100

Neue Issues direkt in Ihr Postfach

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