microsoft / microsoft/TypeScript

Allow composite values to be used in type predicates

Offen
#43,640 2 Kommentare 0 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
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

Allow composite values to be used in type predicates

🔍 Search Terms

Is, composite type, complex type, composite value, complex value, type predicate, type guard

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

⭐ Suggestion

Type predicates allow you to define functions that can tell the TypeScript compiler if a parameter is of a certain type.
I suggest that this be extended to allow type predicates to narrow the type of composite objects involving parameters.
That is, the left-hand-side of is types should be allowed to include object literals.

📃 Example

Say you have a type that involves a subset of another type:

type MyType = {property1: "static text", property2: "Hello" | "World"};

A type predicate for this would always require passing in the property1 property, even though it’s unnecessary.
Now, you can create a type predicate that only takes the value of property2, but still gurantees the result type:

function foo(text: string): {property1: "static text", property2: text} is MyType {
    return ["Hello", "World"].includes(text);
};

I’ve run into the problem of being unable to do this while developing my website.
I had a tagged union:

type A = {t: "A", value: "X" | "Y"};
type B = {t: "B", value: string};
type U = A | B;

And I wanted to get a value of type A from user input, but default back to a B type if the value wasn’t
To do this, I hoped to be able to do this:

function zit(x: string): {t: "A", value: x} is A {
    return ["X", "Y"].includes(x);
};
function gob(x: string): U {
    return zit(x) ? {t: "A", value: x} : {t: "B", value: x};
};

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

Es werden keine Dateien, Tests oder Einstiegspunkte genannt. Beginne damit, die Beispiele für Typprädikate des Issues und das bestehende Verhalten des Compilers bei Typwächtern zu überprüfen; die Änderung wäre vollständig, wenn zusammengesetzte Objekttypen in Prädikaten akzeptiert werden und die gezeigten Narrowing-Szenarien funktionieren, ohne das erzeugte JavaScript zu ändern.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

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

Neue Issues direkt in Ihr Postfach

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