microsoft / microsoft/TypeScript
Suggesion: Allow recursive/self-references in `satisfies` constraint
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.4k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
Suggestion
🔍 Search Terms
satisfies keyword, recursion, recursive, constraint, self referential
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
It would only make previously rejected type assertions possible as it only widens the set of valid type restrictions.
- This wouldn't change the runtime behavior of existing JavaScript code
satisfiesonly exists during type checking and does not in generated JavaScript - This could be implemented without emitting different JS based on the types of the expressions
As above
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
As above
- This feature would agree with the rest of TypeScript's Design Goals.
The same is already possible using a constrained identity function
⭐ Suggestion
It is currently not possible to reference the type of a variable that the satisfies constraint is applied on. Enabling this functionality should not be hard, as the same behavior can be recreated using a constrained identity function, see below. This would enable more precise verification of structures by the type checker.
📃 Motivating Example
// I define a (very simplified) state machine by the following type:
type States<S extends string> = Record<S, S>;
// I can then define a map of machine names to their states records:
const myMachines1 = {
alan: {
a: "b",
b: "c",
c: "c",
},
turing: {
x: "y",
y: "x",
},
} satisfies Record<string, States<string>>;
// Problem: This is possible, though should be invalid:
const myMachines2 = {
foo: {
a: "x",
},
bar: {
x: "a",
}
} satisfies Record<string, States<string>>;
// Solution 1: Identity function with self-referential generic:
function defineMachines<T extends {
[name in keyof T]: States<keyof T[name] & string>;
}>(machines: T) {
return machines;
}
// Valid:
const myMachines3 = defineMachines({
alan: {
a: "b",
b: "c",
c: "c",
},
turing: {
x: "y",
y: "x",
},
});
// Errors:
const myMachines4 = defineMachines({
foo: {
a: "x",
},
bar: {
x: "a",
}
});
// Solution 2: The same behavior should be achievable using the new `satisfies` keyword:
const myMachines5 = {
foo: {
a: "x",
},
bar: {
x: "a",
}
} satisfies {
[name in keyof typeof myMachines5]: States<keyof typeof myMachines5[name] & string>;
};
// But errors: Block-scoped variable 'myMachines5' used before its declaration.
💻 Use Cases
As seen in the example above, this allows for a more precise control over (nested) type restrictions. It is already possible to self-reference type definitions, so why shouldn't this also be possible for variable declarations? The satisfies keyword does not modify the type itself to my knowledge.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con gli esempi motivanti di satisfies e confronta l’autoreferenza rifiutata con la soluzione basata su una funzione identità vincolata. Determina come dovrebbero comportarsi i vincoli ricorsivi per le dichiarazioni di variabili, quindi verifica che le mappe valide delle macchine a stati siano accettate e che i riferimenti incrociati non validi siano rifiutati senza modificare l’output a runtime.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- compilers
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 30/100