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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:46:47  来源:igfitidea点击:

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

typescriptsettimeout

提问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 setTimeoutfunction 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 setTimeoutthat 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 windowobject 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 anynor window.setTimeoutwhich 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.3and 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.Timeoutthat 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;
         }

     ...
     }