TypeScript - use correct version of setTimeout (node vs window)

let timer: ReturnType<typeof setTimeout> = setTimeout(() => { ... });

clearTimeout(timer);

By using ReturnType<fn> you are getting independence from platform. You won't be forced to use neither any nor window.setTimeout which will break if you run the code on nodeJS server (eg. server-side rendered page).


Good news, this is also compatible with Deno!


2021 update

Akxe's answer suggests ReturnType<Type> technique introduced in Typescript 2.3:

let n: ReturnType<typeof setTimeout>;
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);

I guess it depends on where you will be running your code.

If your runtime target is server side Node JS, use:

let timeout: NodeJS.Timeout;
global.clearTimeout(timeout);

If your runtime target is a browser, use:

let timeout: number;
window.clearTimeout(timeout);