0

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

2
  • "I thought mostly about using a Record." - what you are actually looking for is a mapped index type Commented Aug 18, 2024 at 1:02
  • @Bergi well, a Record was known to me to require all keys to be accounted for. I have very little experience with the even slightly advanced parts of TS, thus this was I thought about. I just head about Mapped Index Types the first time and after looking into them, you're most probably right. Commented Aug 18, 2024 at 8:40

1 Answer 1

1

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)
}
Sign up to request clarification or add additional context in comments.

2 Comments

This looks quite promising and I can't wait to get home and try it!
This is fantastic. It solves the problem I had exactly and feels quite elegant. I have also learned a lot about typescript possibilites. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.