简体   繁体   中英

How do I infer the return types of an object of functions?

const actions = {
  setF1: (a: number) => ({
    type: 'a',
    a
  }),
  setF2: (b: string) => ({
    type: 'b',
    b
  })
};

type ActionTypes = ?

export default reducer = (state = {}, action: ActionTypes) => {
  switch (action.type) {
    case 'a':
      console.log(`${action.a} is a number`);
      return {
        ...state,
        a
      }
    case 'b':
      console.log(`${action.b} is a string`);
      return {
        ...state,
        b
      }
    default:
      return state;
  }
};

The goal is every time I add a function to the actions object, the reducer would automatically infer the action return type in the switch statement. I'm trying to avoid the scenario where I need to do something like action: Action1 | Action2 | Action3 action: Action1 | Action2 | Action3 action: Action1 | Action2 | Action3 .

One way of doing that is to use const assertions in your definition of actions so that the compiler doesn't widen your type property to string , the rest is relatively simple.

const actions = {
  setF1: (a: number) => ({
    type: 'a' as const,
    a
  }),
  setF2: (b: string) => ({
    type: 'b' as const,
    b
  })
};

type ActionKeys = keyof typeof actions; // "setF1" | "setF2"
type ActionTypes = ReturnType<typeof actions[ActionKeys]> // { type: "a", a: number } | { type: "b", b: string }

Playground link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM