我正在努力升级一些旧的TypeScript代码以使用最新的编译器版本,而我在调用时遇到问题setTimeout.代码期望调用浏览器的setTimeout函数返回一个数字:
setTimeout(handler: (...args: any[]) => void, timeout: number): number;
但是,编译器正在将此解析为节点实现,它返回NodeJS.Timer:
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
此代码不在节点中运行,但节点类型作为对其他内容的依赖(不确定是什么)而被拉入.
如何指示编译器选择setTimeout我想要的版本?
这是有问题的代码:
let n: number;
n = setTimeout(function () { /* snip */ }, 500);
Run Code Online (Sandbox Code Playgroud)
这会产生编译器错误:
TS2322:类型'定时器'不能分配给'数字'类型.
dhi*_*ilt 56
另一种不影响变量声明的解决方法:
let n: number;
n = <any>setTimeout(function () { /* snip */ }, 500);
Run Code Online (Sandbox Code Playgroud)
此外,应该可以window明确使用该对象,而无需any:
let n: number;
n = window.setTimeout(function () { /* snip */ }, 500);
Run Code Online (Sandbox Code Playgroud)
Akx*_*kxe 25
我建议使用,x: ReturnType<typeof setTimeout>;因为它实际上将独立于所使用的平台工作。
cwo*_*ter 24
我想这取决于您将在哪里运行代码。
如果您的运行时目标是服务器端 Node JS,请使用:
let timeout: NodeJS.Timeout;
global.clearTimeout(timeout);
Run Code Online (Sandbox Code Playgroud)
如果您的运行时目标是浏览器,请使用:
let timeout: number;
window.clearTimeout(timeout);
Run Code Online (Sandbox Code Playgroud)
Ded*_*Dev 21
这对我来说非常有效。
type Timer = ReturnType<typeof setTimeout>
const timer: Timer = setTimeout(() => {}, 1000)
Run Code Online (Sandbox Code Playgroud)
小智 13
这可能适用于旧版本,但使用 TypeScript 版本^3.5.3和 Node.js 版本^10.15.3,您应该能够从Timers模块导入特定于节点的函数,即:
import { setTimeout } from 'timers';
Run Code Online (Sandbox Code Playgroud)
这将返回一个Timeout类型的实例NodeJS.Timeout,您可以将其传递给clearTimeout:
import { clearTimeout, setTimeout } from 'timers';
const timeout: NodeJS.Timeout = setTimeout(function () { /* snip */ }, 500);
clearTimeout(timeout);
Run Code Online (Sandbox Code Playgroud)
还想提一下,规范NodeJS.Timeout包括[Symbol.toPrimitive](): number:
interface Timeout extends Timer {
/**
* If true, the `Timeout` object will keep the Node.js event loop active.
* @since v11.0.0
*/
hasRef(): boolean;
/**
* Sets the timer's start time to the current time, and reschedules the timer to
* call its callback at the previously specified duration adjusted to the current
* time. This is useful for refreshing a timer without allocating a new
* JavaScript object.
*
* Using this on a timer that has already called its callback will reactivate the
* timer.
* @since v10.2.0
* @return a reference to `timeout`
*/
refresh(): this;
[Symbol.toPrimitive](): number;
}
Run Code Online (Sandbox Code Playgroud)
为了兼容性,Node 中的其他超时 API 可以很好地处理普通整数 ID,它们不需要接受对象。这些对象在“服务器”端使用,以允许对保持进程活动和垃圾收集内容进行更精细的控制。例如:
function clearTimeout(timeoutId: NodeJS.Timeout | string | number | undefined): void;
Run Code Online (Sandbox Code Playgroud)
setTimeout这意味着您可以对and的结果使用原始转换setInterval:
let timeoutId: number | undefined;
timeoutId = Number(setTimeout(callback, ms));
function clear() {
clearTimeout(timeoutId);
}
Run Code Online (Sandbox Code Playgroud)
不会与任何一个 API 冲突,同时如果您需要依赖它作为其他 API 合约的原始值,也不会在以后遇到类型问题。
我遇到了同样的问题,我们团队决定使用的解决方法就是使用"any"作为计时器类型.例如:
let n: any;
n = setTimeout(function () { /* snip */ }, 500);
Run Code Online (Sandbox Code Playgroud)
它将与setTimeout/setInterval/clearTimeout/clearInterval方法的两种实现一起使用.
| 归档时间: |
|
| 查看次数: |
26769 次 |
| 最近记录: |