Reputation: 13
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 ?
Upvotes: 1
Views: 999
Reputation: 455
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[]
Upvotes: 2