TypeScript - 使用正确版本的 setTimeout(节点与窗口) [英] TypeScript - use correct version of setTimeout (node vs window)
问题描述
我正在升级一些旧的 TypeScript 代码以使用最新的编译器版本,但在调用 setTimeout
时遇到了问题.代码期望调用浏览器的 setTimeout
函数,该函数返回一个数字:
I am working on upgrading some old TypeScript code to use the latest compiler version, and I'm having trouble with a call to setTimeout
. The code expects to call the browser's setTimeout
function which returns a number:
setTimeout(handler: (...args: any[]) => void, timeout: number): number;
然而,编译器将其解析为节点实现,它返回一个 NodeJS.Timer:
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;
此代码不在 node 中运行,但 node 类型被引入作为对其他东西的依赖(不确定是什么).
This code does not run in node, but the node typings are getting pulled in as a dependency to something else (not sure what).
如何指示编译器选择我想要的 setTimeout
版本?
How can I instruct the compiler to pick the version of setTimeout
that I want?
这是有问题的代码:
let n: number;
n = setTimeout(function () { /* snip */ }, 500);
这会产生编译器错误:
TS2322: Type 'Timer' is notassignable to type 'number'.
TS2322: Type 'Timer' is not assignable to type 'number'.
推荐答案
2021 更新
Akxe 的回答建议在 Typescript 2.3 中引入 ReturnType
技术:
Akxe's answer suggests ReturnType<Type>
technique introduced in Typescript 2.3:
let n: ReturnType<typeof setTimeout>;
n = setTimeout(cb, 500);
它很好,似乎比显式转换更受欢迎.但是n"的结果类型是在这种情况下是NodeJS.Timeout",可以按如下方式使用它:
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);
ReturnType/NodeJS.Timeout 方法的唯一问题是浏览器特定环境中的数字操作仍然需要转换:
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);
}
原答案
不影响变量声明的解决方法:
A workaround that does not affect variable declaration:
let n: number;
n = setTimeout(function () { /* snip */ }, 500) as unknown as number;
此外,在特定于浏览器的环境中,可以使用 window
对象而无需强制转换:
Also, in browser-specific environment it is possible to use window
object with no casting:
let n: number;
n = window.setTimeout(function () { /* snip */ }, 500);
这篇关于TypeScript - 使用正确版本的 setTimeout(节点与窗口)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!