Mihail Malostanidis
Mihail Malostanidis

Reputation: 3014

Overloads not typechecking body

Does TypeScript not check the function body against function overloads at all? The following compiles, although it clearly isn't doing what it claims:

function a(input: string): string
function a(input: number): number
function a(input: string | number): string | number {
  if (typeof input === "string") return 42
  return "banana"
}

Is my third signature at fault? The catch-all signature isn't appearing in the resulting type, and I don't know of a way to declare the function without it, any attempt is met with the Overload signature is not compatible with function implementation. error.

typeof a = {
    (input: string): string;
    (input: number): number;
}

I would accept switching to the more explicit intersect type:

type C = ((input: number) => number) & ((input: string) => string)

But I don't understand how to actually create a function satisfying it without using overload syntax, which seems like a forced cast. I asked about that in Overloaded function type in typescript question.

Edit: the first block is a minimalist contrived example. You can test it with the following:

const number: number = a(0)
console.log("number", typeof number, number)

outputs number string banana

const string: string = a("")
console.log("string", typeof string, string)

outputs string number 42

Edit 2: This isn't a duplicate of Overloaded function type in typescript, I am asking about typechecking the function implementation against all overloads, that question is about fulfilling an overload type with a new function.

Upvotes: 4

Views: 367

Answers (1)

artem
artem

Reputation: 51689

Does TypeScript not check the function body against function overloads at all?

No it does not check the body against overload declarations.

As you've seen, it checks that implementation signature is compatible with all overload declarations; and it checks that the body conforms to the implementation signature; that's all. Also, the implementation signature is not taken into account when doing overload resolution at the call site.

Enforcing implementation conformance with overloaded declarations was not the design goal, at least that's how I interpret this statement from the FAQ:

The rationale here is that since JavaScript does not have function overloading, you will be doing parameter checking in your function, and this your function implementation might be more permissive that what you would want your users to call you through.

Upvotes: 3

Related Questions