Is it possible to create an overloaded function type without specifying a concrete function? By examining the type of an overloaded function, it appears that using multiple call signatures on an interface or object type is the recommended approach:
function a(input: string): string
function a(input: number): number
function a(input: string | number): string | number {
return input
}
type A = typeof a
type B = {
(input: string): string
(input: number): number
}
const b: B = a // Works fine!
It's also worth noting that defining a union type with the same concept (without requiring a catch-all case for overloads) also functions correctly, with types being interchangeable in both directions!
type C = ((input: number) => number) & ((input: string) => string)
const c: C = b // No issues!
const a2: A = c // Also works without problems!
But how do you go about creating a function that matches this type? Is overloading necessary?
const x: A = (input: string | number) => input
and
const y: A = (input: string | number) => {
if (typeof input === "number") return input
if (typeof input === "string") return input
throw "error"
}
Both attempts result in the same error message:
Type '(input: string | number) => string | number' is not assignable to type '{ (input: string): string; (input: number): number; }'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
This issue persists even when using the less clear union type C
Type '(input: string | number) => string | number' is not assignable to type 'C'.
Type '(input: string | number) => string | number' is not assignable to type '(input: number) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
Hopefully, there may be a simple fix to my mistake. If not, what are the recommended solutions when needing a function to handle various call signatures with corresponding return types?