TypeScript - 使用正确版本的 setTimeout(节点与窗口) [英] TypeScript - use correct version of setTimeout (node vs window)

查看:123
本文介绍了TypeScript - 使用正确版本的 setTimeout(节点与窗口)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在升级一些旧的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆