Typescript: Wrong overload selection based on function return type

Multi tool use
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.
declare function
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!
1 Answer
1
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.
setInterval(() => console.log('hi'), 1000);
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
setInterval(() => console.log('hi'), 1000);
number
Timer
Timer
setInterval
window.setInterval
@alisabzevari My recommendation then is to remove the
dom
lib from the default libs. For example: "lib": ["es2018", "scripthost"]
. This will remove setInterval
from the global namespace and leave just the ndoe version around.– Titian Cernicova-Dragomir
Jul 2 at 7:14
dom
"lib": ["es2018", "scripthost"]
setInterval
I actually want to use
setInterval
from dom
. I have to remove node
from type definitions, but this has been added from one of my node_modules packages.– alisabzevari
2 days ago
setInterval
dom
node
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thanks for your answer. The first
setInterval
definition pasted from node's type definitions in definitely typed. I don't think writingwindow.setInterval
is a clean way of fixing this problem. What would be the best fix for this? Changing type definition of node in definitely typed?– alisabzevari
Jul 1 at 21:17