TypeScript - 使用正确版本的 setTimeout(节点与窗口)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45802988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript - use correct version of setTimeout (node vs window)
提问by Kevin Tighe
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:
我正在升级一些旧的 TypeScript 代码以使用最新的编译器版本,但在调用setTimeout
. 代码期望调用setTimeout
返回一个数字的浏览器函数:
setTimeout(handler: (...args: any[]) => void, timeout: number): 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:
但是,编译器将其解析为节点实现,它返回一个 NodeJS.Timer:
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): 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?
如何指示编译器选择setTimeout
我想要的版本?
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'.
TS2322:“定时器”类型不可分配给“数字”类型。
采纳答案by dhilt
Another workaround that does not affect variable declaration:
另一个不影响变量声明的解决方法:
let n: number;
n = <any>setTimeout(function () { /* snip */ }, 500);
Also, it should be possible to use the window
object explicitly without any
:
此外,应该可以在window
没有以下情况下显式使用对象any
:
let n: number;
n = window.setTimeout(function () { /* snip */ }, 500);
回答by Akxe
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 any
nor window.setTimeout
which willbreak if you run the code no nodeJS server (eg. server-side rendered page).
通过使用,ReturnType<fn>
您将独立于平台。你不会被强制使用any
,也没有window.setTimeout
哪个会,如果你运行的代码没有服务器的NodeJS(如服务器端渲染页面)打破。
Good news, this is also compatible with Deno!
好消息,这也兼容 Deno!
回答by cwouter
I guess it depends on where you will be running your code.
我想这取决于您将在哪里运行代码。
If your runtime target is server side Node JS, use:
如果您的运行时目标是服务器端 Node JS,请使用:
let timeout: NodeJS.Timeout;
global.clearTimeout(timeout);
If your runtime target is a browser, use:
如果您的运行时目标是浏览器,请使用:
let timeout: number;
window.clearTimeout(timeout);
回答by Nick Bernard
This will likely work with older versions, but with TypeScript version ^3.5.3
and Node.js version ^10.15.3
, you should be able to import the Node-specific functions from the Timersmodule, i.e.:
这可能适用于旧版本,但使用 TypeScript 版本^3.5.3
和 Node.js 版本^10.15.3
,您应该能够从Timers模块导入特定于节点的函数,即:
import { setTimeout } from 'timers';
That will return an instance of Timeoutof type NodeJS.Timeout
that you can pass to clearTimeout
:
这将返回一个Timeout类型的实例NodeJS.Timeout
,您可以将其传递给clearTimeout
:
import { clearTimeout, setTimeout } from 'timers';
const timeout: NodeJS.Timeout = setTimeout(function () { /* snip */ }, 500);
clearTimeout(timeout);
回答by Mark Dolbyrev
I faced the same problem and the workaround our team decided to use, was just to use "any" for the timer type. E.g.:
我遇到了同样的问题,我们团队决定使用的解决方法是对计时器类型使用“任何”。例如:
let n: any;
n = setTimeout(function () { /* snip */ }, 500);
It will work with both implementations of setTimeout/setInterval/clearTimeout/clearInterval methods.
它将与 setTimeout/setInterval/clearTimeout/clearInterval 方法的两种实现一起使用。
回答by Nikola Lukic
If you wanna real solution for typescript about timers here we go :
Bug is in return type 'number' it is not Timer or anything else.
This is for typescripts version ~ >2.7 solution :
如果你想真正解决关于定时器的打字稿,我们去:
错误是返回类型“数字”,它不是计时器或其他任何东西。
这是打字稿版本〜> 2.7解决方案:
export type Tick = null | number | NodeJS.Timer;
export type Tick = null | number | NodeJS.Timer;
Now we fixed all, just declare like this:
现在我们解决了所有问题,只需像这样声明:
import { Tick } from "../../globals/types";
export enum TIMER {
INTERVAL = "INTERVAL",
TIMEOUT = "TIMEOUT",
};
interface TimerStateI {
timeInterval: number;
}
interface TimerI: TimerStateI {
type: string;
autoStart: boolean;
isStarted () : bool;
}
class myTimer extends React.Component<TimerI, TimerStateI > {
private myTimer: Tick = null;
private myType: string = TIMER.INTERVAL;
private started: boll = false;
constructor(args){
super(args);
this.setState({timeInterval: args.timeInterval});
if (args.autoStart === true){
this.startTimer();
}
}
private myTick = () => {
console.log("Tick");
}
private startTimer = () => {
if (this.myType === TIMER.INTERVAL) {
this.myTimer = setInterval(this.myTick, this.timeInterval);
this.started = true;
} else if (this.myType === TIMER.TIMEOUT) {
this.myTimer = setTimeout(this.myTick, this.timeInterval);
this.started = true;
}
}
private isStarted () : bool {
return this.started;
}
...
}