Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to call a function from another function, but keep all of the types for that specific function

I have use case, where I want to register multiple functions, and then call them from another function.

Here’s the code

const combineFunctions = <T extends Record<keyof T, T[keyof T]>>(funcs: T) => {
  return (key: keyof T, params: Parameters<T[keyof T]>): ReturnType<T[keyof T]> => funcs[key](params)
}

interface AddNumbersArgumentsType {
  a: number
  b: number
}

type AddNumbersReturnType = number

const addNumbers = (params: AddNumbersArgumentsType): AddNumbersReturnType => {
  return params.a + params.b
}

interface CombineStringWithNumberArgumentsType {
  c: string
  d: number
}

type CombineStringWithNumberReturnType = string

const combineStringWithNumber = (params: CombineStringWithNumberArgumentsType): CombineStringWithNumberReturnType => {
  return params.c + params.d
}

const funcs = {
  addNumbers,
  combineStringWithNumber
}

const funkies = combineFunctions<typeof funcs>(funcs)

const a = funkies('addNumbers', [{ // Here Paramters util function forces me to send an array
  // Here it should autocomplete only correct params from AddNumbersArgumentsType
  // But it gives me an option of all arguments all functions take
}]) // => Return type is not gotten correctly, but is a combinations of all functions return types

Main problems being

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • Parameters util forces me to use an array while I just want to get the type of params
  • Arguments autocomplete for all params from all functions instead of taking argument types specific to the function
  • Same problem with return type as with arguments

You can see the code running here

Thanks in advance 🙂

>Solution :

You need an extra type parameter on the inner function to capture the actual key passed in, and use that instead of keyof T to index into T. That will bake ts resolve the actual function being passed in.

Parameters returns a tuple of parameters (there could be more) but you can use tuple and rest parameters to fix this.

const combineFunctions = <T extends Record<PropertyKey, (...a: any[]) => any>>(funcs: T) => {
  return <K extends keyof T>(key: K, ...params: Parameters<T[K]>): ReturnType<T[K]> => funcs[key](...params) 
}

///.....
const funcs = {
  addNumbers,
  combineStringWithNumber
}

const funkies = combineFunctions<typeof funcs>(funcs)

const a = funkies('addNumbers', {a: 1, b: 1}) // all type cheked

Playground Link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading