alisabzevari
alisabzevari

Reputation: 8136

Typescript: Wrong overload selection based on function return type

Why the following code is a compile error:

export interface Timer { }
declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): Timer;
declare function setInterval(handler: (...args: any[]) => void, timeout: number): number;

const timer: number = setInterval(() => console.log('hi'), 1000);

Also, when I change the order of declare function statements, it compiles the code without any errors. Looks like compiler just accepts the first type declaration.

EDIT: I couldn't provide a link to playground because the url was not correctly formatted in the question and I couldn't use any url shortener!

Upvotes: 1

Views: 480

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249706

The problem is that Typescript does not (usually) take into account the expected call site return type when resolving function signatures. In your case just looking at setInterval(() => console.log('hi'), 1000); the compiler can say that this call could resolve to either signature, so it picks the first one in declaration order (as specified in the compiler specs). Once it has picked an overload the compiler will not reverse the decision if later, on assignment an error occurs.

The real problem to me seems to be that in deed, even I, lookin at setInterval(() => console.log('hi'), 1000); can't tell if it will return a number or a Timer. There is nothing distinguishing between a call with two arguments returning a number, and a call to the version with two arguments and an empty rest parameter returning a Timer

Upvotes: 2

Related Questions