Search code examples
typescript

Typescript record based on object containing functions


I have an object of function definitions which I can not change. It has the following shape:

const _fns = {
  doA: (arg: string): void => someFuncA(arg),
  doB: (arg: number): void => someFuncB(arg)
};

I need to create another object, with the following goals:

  • every single key from _fns needs to be present. For that reason, I thought mostly about using a Record.
  • I need to extend the function parameters. I've found something here, but I'm not even getting this far... For example:
// in _fns
doC: (arg: boolean) => void
// in our new object
doC: (e: Event, arg: boolean) => void

So, basically I'd like a Record which along those lines:

const newFns: Record<T is keyof typeof _fns, _fns[T]+argsExtended> = {
  // e and arg should have their types defined by the extended 
  // function signature pulled from _fns
  doA: (e, arg) => someOtherFunctionForA(e, arg),
  ...
}

I'm pretty sure it must be doable, but I can't even figure out the syntax to get 'Record param 1 is key, use key in param 2 to determine type'.


Solution

  • What about a utility type like this?

    type ExtendFns<TObj extends Record<string, ((...args: never[]) => void)>> = {
      [K in keyof TObj]: ((e: Event, ...args: Parameters<TObj[K]>) => ReturnType<TObj[K]>) 
    }
    

    This way you can create your newFns object like this:

    const newFns: ExtendFns<typeof _fns> = {
      doA: (e, arg) => someOtherFunctionForA(e, arg),
      doB: (e, arg) => someOtherFunctionForB(e, arg)
    }