typescript - Poți extrage semnătura tuturor metodelor dintr-o clasă?


presupunând că am această clasă:

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 ...
}

Toate metodele clasei returnează un obiect similar: {type: string, payload: Record<string, number>}

Totuși, aș vrea să fiu mai strict. Vreau să fie

type ReturnedActions = 
| { type: 'foo', {a: string, b:string} } 
| { type: 'bar', {c: string, e:string} } 
...

pentru că atunci pot folosi un switch pentru a filtra după tip:

declare var a: ReturnedActions 

switch (a.type) {
  case 'foo': 
    payload.c // error
}

Știu că pot să fac

var actions = new Actions(); 
type = ReturnType<typeof actions.someAction1> |  ReturnType<typeof actions.someAction2>

Totuși, această clasă are sute de linii. Există vreo modalitate de a extrage toate valorile posibile de returnare din toate metodele din clasă fără a le face manual?

Folosesc versiunea "typescript": "3.7.2"

Răspuns #1

Poți folosi un tip mapat pentru a parcurge proprietățile clasei și un tip condițional pentru a filtra metodele și a extrage tipul de returnare. Apoi indexezi acest tip mapat pentru a obține reuniunea tuturor valorilor posibile din tipul mapat

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>

Link către terenul de joacă

Editați Dacă Actions conține doar funcții, puteți folosi de asemenea natura distributivă a ReturnType pentru a obține tipul de întoarcere al tuturor funcțiilor din Actions:

type AllActions = ReturnType<Actions[keyof Actions]>;