generics - Hur kan jag få typen av en funktionsanrop i TypeScript?
Hur kan jag få typen av en generisk funktion som tillämpas på en parameter i TypeScript?
Till exempel, hur skulle jag kunna definiera Apply nedan?
declare function f<T>(t: T): T extends number ? boolean : object;
type ResForNumArg = Apply<typeof f, number>; // should be boolean
type ResForStringArg = Apply<typeof f, object>; // should be object
lekplatslänk
Om det inte finns något sätt att göra detta kan man kringgå problemet för specifika fall genom att göra en typalias som är en typnivåversion av funktionen, som F nedan:
declare function f<T>(t: T): T extends number ? boolean : object;
type ApplyF<T> = T extends number ? boolean : object;
type ResForNumArg = ApplyF<number>; // boolean
type ResForStringArg = ApplyF<object>; // object
Men ApplyF kan hamna ur synk med f och är irriterande att skriva. Finns det ett bättre sätt?
Uppdatering: detta verkar vara relaterat till https://github.com/microsoft/TypeScript/issues/29043
Svar #1
Som du korrekt har upptäckt är det inte möjligt att använda funktionsdeklaration som generisk typ, det är inte möjligt att använda generiken utan funktionskörning. Vi kan endast använda generiken vid anrop av funktionen (eller kommer att härledas från argumentet):
const r1 = f<number>(1) // boolean
const r2 = f(1) // boolean
Okej, så vi förstår att det inte är möjligt. Nu lösningen, för att få det att fungera utan att förlora anslutningen med den ursprungliga deklarationen föreslår jag en ytterligare generisk typ FType. Betrakta:
type FType<T> = (t: T) => T extends number ? boolean : object;
// join function declaration with FType:
declare function f<T>(...t: Parameters<FType<T>>): ReturnType<FType<T>>
type ResForNumArg = ReturnType<FType<number>>; // bool
type ResForStringArg = ReturnType<FType<object>>; // object
Genom att använda hjälptyperna Parameters och ReturnType kopplade jag FType med funktionsdeklarationen f. Det är omständligt men vi får vad vi vill till slut och FType kan användas på det vanliga sättet.
Lekplatslänk
