网站搜索

typescript - 你能提取一个类中所有方法的签名吗?


假设我有这个类:

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

所有类方法都返回一个类似的对象:{type: string, payload: Record<string, number>}

然而,我想更严格一些。我希望它是

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

因为那样我可以用开关按类型过滤:

declare var a: ReturnedActions 

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

我知道我能做到

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

然而,这个类有几百行代码。有没有办法从类中的所有方法中提取所有可能的返回值,而不用手动去做?

我正在使用版本 "typescript": "3.7.2"

答案#1

你可以使用映射类型遍历类的属性,并使用条件类型过滤方法并提取返回类型。然后你索引这个映射类型以获取映射类型中所有可能值的联合类型。

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>

游乐场链接

编辑 如果 Actions 仅包含函数,您也可以使用 ReturnType 的分配性质来获取 Actions 中所有函数的返回类型:

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