principletypescriptCritical
TypeScript - use correct version of setTimeout (node vs window)
Viewed 0 times
typescriptusecorrectsettimeoutwindownodeversion
Problem
I am working on upgrading some old TypeScript code to use the latest compiler version, and I'm having trouble with a call to
However, the compiler is resolving this to the node implementation instead, which returns a NodeJS.Timer:
This code does not run in node, but the node typings are getting pulled in as a dependency to something else (not sure what).
How can I instruct the compiler to pick the version of
Here is the code in question:
This produces the compiler error: TS2322: Type 'Timer' is not assignable to type 'number'.
setTimeout. The code expects to call the browser's setTimeout function which returns a number:setTimeout(handler: (...args: any[]) => void, timeout: number): number;However, the compiler is resolving this to the node implementation instead, which returns a NodeJS.Timer:
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;This code does not run in node, but the node typings are getting pulled in as a dependency to something else (not sure what).
How can I instruct the compiler to pick the version of
setTimeout that I want?Here is the code in question:
let n: number;
n = setTimeout(function () { /* snip */ }, 500);This produces the compiler error: TS2322: Type 'Timer' is not assignable to type 'number'.
Solution
2021 update
Akxe's answer suggests
It is nice and seems to be preferred over explicit casting. But the result type of "n" in this case is "NodeJS.Timeout", and it is possible to use it as follows:
The only problem with ReturnType/NodeJS.Timeout approach is that numeric operations in browser-specific environment still require casting:
Original answer
A workaround that does not affect variable declaration:
Also, in browser-specific environment it is possible to use
Akxe's answer suggests
ReturnType technique introduced in Typescript 2.3:let n: ReturnType;
n = setTimeout(cb, 500);It is nice and seems to be preferred over explicit casting. But the result type of "n" in this case is "NodeJS.Timeout", and it is possible to use it as follows:
let n: NodeJS.Timeout;
n = setTimeout(cb, 500);The only problem with ReturnType/NodeJS.Timeout approach is that numeric operations in browser-specific environment still require casting:
if ((n as unknown as number) % 2 === 0) {
clearTimeout(n);
}Original answer
A workaround that does not affect variable declaration:
let n: number;
n = setTimeout(function () { / snip / }, 500) as unknown as number;
Also, in browser-specific environment it is possible to use
window object with no casting:let n: number;
n = window.setTimeout(function () { / snip / }, 500);
Code Snippets
let n: ReturnType<typeof setTimeout>;
n = setTimeout(cb, 500);let n: NodeJS.Timeout;
n = setTimeout(cb, 500);if ((n as unknown as number) % 2 === 0) {
clearTimeout(n);
}Context
Stack Overflow Q#45802988, score: 309
Revisions (0)
No revisions yet.