microsoft / microsoft/TypeScript
Proposal: repurpose "is" operator for a narrowing version of "satisfies"
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
🔍 Search Terms
satisfies with narrowing
narrowing literals
satisfias, satisfiesas, sassafras
✅ Viability Checklist
- 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 isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
⭐ Suggestion
A narrowing version of the satisfies operator
type Animal = "cat" | "dog";
const animal = "cat" is Animal;
/// ^? = Animal
📃 Motivating Example
Consider an API where the return type is influenced by the input type. For example, this simplification of Tanstack Form (I'm not a contributor to it, but I'm developing something similar).
function useForm<T>(defaultValues: T): T {
return /*something*/;
}
const values = useForm({
animal: "cat"
});
The type inferred from animal here is string.
This works fine if animal is a text input in our form, but what if we want it to be an enumeration, e.g. <select>, and also retain some compile-time typechecking? e.g. we want to prevent this
values.animal = "red"
satifies will error if the initial value is not valid, but it doesn't narrow the type:
// #1
const values = useForm({
animal: "cat" satisfies Animal
});
// typeof values["animal"] = string
as achieves the equivalent of narrowing here, but it masks some errors:
// #2
const values = useForm({
animal: "red" as Animal // no error
});
I propose to repurpose the existing is keyword. Could use another keyword; bikeshed it later.
const values = useForm({
animal: "cat" is Animal
});
This would produce a compiler error if the left hand side was not an Animal (like satifies), but additionally narrow the type to Animal.
💻 Use Cases
What shortcomings exist with current approaches?
A more natural flow of the code is disrupted; the field can't be declared inline.
What workarounds are you using in the meantime?
This one is okay, but somewhat disrupts the flow of reading top to bottom.
// #3
const initialAnimal: Animal = "cat";
const values = useForm({
animal: initialAnimal,
plainString: "a",
plainNumber: 1
});
This one requires declaring the entire type separately. Also there may be many more type args than just the data shape. This is the case in Tanstack Form. You'd need useForm<FormValues, Blah, Blah, Blah, ...>;
// #4
type FormValues = {
animal: Animal
}
const values = useForm<FormValues>({
animal: "cat"
});
This is probably what I find myself reaching for, but as with #4 requires declaring the entire type
// #5
type FormValues = {
animal: Animal
plainString: string
plainNumber: number
}
const initialValues: FormValues = {
animal: "cat",
plainString: "",
plainNumber: 0
}
const values = useForm(initialValues);
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
Es werden keine Implementierungsdateien, Tests oder Einstiegspunkte genannt. Beginne damit, den vorhandenen Operator satisfies und das in den Beispielen beschriebene Verhalten von Typassertionen zu prüfen, und bestimme anschließend, wie eine einschränkende Form von is in das Typsystemdesign des Compilers passen würde. Erledigt ist die Aufgabe, wenn der Vorschlag ein akzeptiertes Design sowie einen definierten Umfang für Implementierung und Tests enthält.
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
- 30/100