generics - Högre ordningens typfunktioner i TypeScript?
Vänligen överväg följande pseudokod som försöker definiera en högre ordningens typfunktion med en funktions-typad parameter M<?>:
type HigherOrderTypeFn<T, M<?>> = T extends (...)
? M<T>
: never;
M<?> är syntaktiskt inkorrekt TypeScript, men att deklarera typesignaturen som HigherOrderTypeFn<T, M> ger felet Type 'M' is not generic. ts(2315) på den andra raden.
Har jag rätt att anta att en sådan typ för närvarande inte kan representeras i TS?
Svar #1
Du har rätt, det är för närvarande inte representerbart i TypeScript. Det finns en långvarig öppen GitHub-förfrågan om funktionalitet, microsoft/TypeScript#1213, som förmodligen borde ha titeln något i stil med "stöd för högre ordningens typer" men för närvarande har titeln "Tillåt att klasser kan vara parametriska i andra parametriska klasser".
Det finns några idéer i diskussionen om hur man kan simulera sådana högre ordnade typer i det nuvarande språket (se den här kommentaren för ett konkret exempel), men enligt min åsikt hör de förmodligen inte hemma i produktionskod. Om du har någon specifik struktur som du försöker implementera, kanske något lämpligt kan föreslås.
Men i vilket fall, om du vill öka chansen (förmodligen försumbart, tyvärr) att detta någonsin händer, kanske du vill gå till det ärendet och ge det en 👍 och/eller beskriva ditt användningsfall om du tycker att det är särskilt övertygande jämfört med det som redan finns där. !
Svar #2
För dig och andra som söker en lösning kan du prova en enkel idé baserad på platshållare (se denna kommentar i diskussionen som nämns av jcalz):
type Placeholder = {'aUniqueKey': unknown};
type Replace<T, X, Y> = {
[k in keyof T]: T[k] extends X ? Y : T[k];
};
Så, din funktion skulle se ut som följer:
type HigherOrderTypeFn<T, M> = T extends (...) ? Replace<M, Placeholder, T> : never;
och kallas till exempel så här:
type M<U> = U[];
type X = HigherOrderTypeFn<number, M<Placeholder>> // is number[] (if ... is number)
