typescript - Kan du extrahera signaturen för alla metoder i en klass?
förutsatt att jag har den här klassen:
class Actions {
static FooAction = 'foo' as const;
someAction1() {
return {
type: Actions.FooAction,
payload: {a: 1, b:2}
}}
static BarAction = 'bar' as const;
someAction2() {
return {
type: Actions.BarAction,
payload: {c: 3, e:2}
}}
... keeps going ...
}
Alla klassmetoder returnerar ett liknande objekt: {type: string, payload: Record<string, number>}
Men jag skulle vilja vara mer strikt. Jag vill att det ska vara
type ReturnedActions =
| { type: 'foo', {a: string, b:string} }
| { type: 'bar', {c: string, e:string} }
...
eftersom då kan jag använda en switch för att filtrera efter typ:
declare var a: ReturnedActions
switch (a.type) {
case 'foo':
payload.c // error
}
Jag vet att jag kan göra
var actions = new Actions();
type = ReturnType<typeof actions.someAction1> | ReturnType<typeof actions.someAction2>
Men denna klass är hundratals rader lång. Finns det ett sätt att extrahera alla möjliga returvärden från alla metoder i klassen utan att göra det manuellt?
Jag använder version "typescript": "3.7.2"
Svar #1
Du kan använda en mappad typ för att gå igenom klassens egenskaper och en villkorlig typ för att filtrera metoder och extrahera returtypen. Du indexerar sedan denna mappade typ för att få unionen av alla möjliga värden i den mappade typen.
type ReturnedActions<T> = {
[P in keyof T]: T[P] extends (...a: any) => infer R ? {
type: P,
payload: R
} : never
}[keyof T]
type AllActions = ReturnedActions<Actions>
Lekplatslänk
Redigera Om Actions endast innehåller funktioner kan du också använda ReturnTypes distributiva natur för att få returtypen för alla funktioner i Actions:
type AllActions = ReturnType<Actions[keyof Actions]>;
