Home > other >  Merge return types of interface containing functions
Merge return types of interface containing functions

Time:07-01

Let's say we have an object containing some functions:

const handlers = {
  handler1: (state: State, payload: boolean) => ({
    schema: payload,
    errors: [],
  }),
  handler2: (state: State, payload: string[]) => ({
    errors: payload,
  }),
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  reset: (...args: any) => initialState,
}

I need to define a type that merges their return types like

State | {
  schema: boolean,
  errors: never[]
} | {
  errors: string[]
}

One simple solution could be

type MergeReturnTypes1 = ReturnType<typeof handlers[keyof typeof handlers]>

However I'm not getting why the following type definition

type MergeReturnType2<H> = H extends Record<string, (...args: any) => infer T> ? T : never

Is only return the return type of the first function contained in the handlers object

type T = MergeReturnType2<typeof handlers>

T = {
  schema: boolean
  errors: never[]
}

CodePudding user response:

I am honestly not sure why this is not working but I'm still trying to figure out an explanation.

You can fix the problem by using T to infer the whole function in the Record instead of only inferring the return type.

type MergeReturnType2<H> = H extends Record<string, infer T extends (...args: any) => any> 
  ? ReturnType<T> 
  : never

type T = MergeReturnType2<typeof handlers>

// type T = State | {
//     schema: boolean;
//     errors: never[];
// } | {
//     errors: string[];
// }

Playground

  • Related