1

I am trying to create a higher order function that takes a callback function and returns an anonymous function which in turn returns the result of callback function. The returned anonymous function takes a parameter called number (n). I use this parameter as a condition for the type of result that is returned by the anonymous function. Basically if number is greater than 1 return an array of results of callback function else return the result of callback function. But I can't seem to get this function overloading definitions work with generic types.

export type ReturnedFunctionType<T> = {
  (): T
  (n: number): T[]
  (n?: number): T | T[]
}

export function higherOrderFn<T> (cb: () => T): ReturnedFunctionType<T> {
  return function (n = 1) {
    if (n === 1) {
      return cb()
    } else {
      return Array(n).fill(null).map(_ => cb())
    }
  }
}

The error says:

Type '(n?: number) => T | T[]' is not assignable to type 'ReturnedFunctionType<T>'.
  Type 'T | T[]' is not assignable to type 'T[]'.
    Type 'T' is not assignable to type 'T[]'.

Can somebody explain me why can't I do this? Or how can I correctly type such function ?

2
  • It think the best option is "export type ReturnedFunctionType<T> = (n?: number) => T | T[];". Commented Jan 19, 2021 at 12:28
  • Yes it silents the error. But there should be a way I could know the exact type of the returned value depending on how I call the function, right? Commented Jan 19, 2021 at 13:25

1 Answer 1

2

I think you need to name your overloaded function. something like this should work

export function higherOrderFn<T> (cb: () => T) {
  function foo(n?: 1): T
  function foo(n: number): T[]
  function foo(n?: number): T | T[]   
   function foo(n = 1) {
    if (n === 1) {
      return cb()
    } else {
      return Array(n).fill(null).map(_ => cb())
    }
  }
  return foo;
}

const foobar = higherOrderFn(() => {})
const foo1 = foobar() // return type void
const foo2 = foobar(1) // return type void
const foo3 = foobar(2) // return type void[]

Playground

Sign up to request clarification or add additional context in comments.

1 Comment

@SagarAcharya can you accept the answer if this solves your problem

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.