Array.map wraps overloaded function return type in additional array

18 hours ago 2
ARTICLE AD BOX

I have an overloaded function type

type MaybeElementwise = { <T extends number>(x: T): T <T extends number>(x: T[]): T[] }

and an implementation:

const f = (<T extends number>(maybeArray: T | T[]) => Array.isArray(maybeArray) ? (maybeArray as T[]).map((v) => 2 * v) : 2 * maybeArray) as MaybeElementwise

TypeScript correctly infers that calling the function with a number returns a number, and calling the function with an array of numbers gives an array of numbers.

f(5) // inferred as number f([1,2,3]) // inferred as number[]

However when I use map, an additional array is inferred. The return type is inferred correctly only when I add an anonymous function to explicitly apply to each element.

[1,2,3].map(f) // inferred as number[][] [1,2,3].map((v) => f(v)) // inferred as number[]

Obviously the map is redundant in this case, but I am curious how the inferred type gets wrapped in an additional array. This seems to be incompatible with both overload signatures, since it would correspond to (x: T): T[]?

Link to playground

Read Entire Article