TypeScript - 使用正确版本的setTimeout(节点与窗口)

时间:2017-08-21 17:49:53

标签: typescript

我正在努力升级一些旧的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);

这会产生编译错误:

TS2322:Type' Timer'不能指定类型'数字'。

9 个答案:

答案 0 :(得分:38)

另一种不影响变量声明的解决方法:

let n: number;
n = <any>setTimeout(function () { /* snip */  }, 500);

此外,应该可以在没有window的情况下明确使用any对象:

let n: number;
n = window.setTimeout(function () { /* snip */  }, 500);

答案 1 :(得分:6)

我遇到了同样的问题,我们团队决定使用的解决方法就是使用“any”作为计时器类型。 E.g:

let n: any;
n = setTimeout(function () { /* snip */  }, 500);

它将与setTimeout / setInterval / clearTimeout / clearInterval方法的两种实现一起使用。

答案 2 :(得分:2)

这可能适用于旧版本,但是对于TypeScript版本$('.two-slider').slick({ slidesToShow: 2, slidesToScroll: 1, draggable: false, infinite: true, // autoplay: true, // autoplaySpeed: 3000, responsive: [ { breakpoint: 768, settings: { slidesToShow: 1, } } ] }); if($('.two-slider:not(.slick-cloned)').length > 1){ $('.two-slider').slick(); } else { $('.two-slider').slick({ slidesToShow: 1, slidesToScroll: 1, draggable: false, infinite: false, responsive: [ { breakpoint: 768, settings: { slidesToShow: 1, } } ] }); } 和Node.js版本^3.5.3,您应该能够从Timers模块导入特定于节点的功能,即:

^10.15.3

这将返回类型import { setTimeout } from 'timers'; 的{​​{3}}实例,您可以将其传递给NodeJS.Timeout

clearTimeout

答案 3 :(得分:1)

  • 如果您想在这里找到有关计时器的打字稿的真正解决方案,请执行以下操作:

    错误返回类型为“数字”,它不是计时器或其他任何内容。

    这是用于打字稿版本的〜> 2.7解决方案:

  

export type Tick = null | number | NodeJS.Timer;

现在,我们修复了所有这样的黄麻声明:

 import { Tick } from "../../globals/types";

 export enum TIMER {
    INTERVAL = "INTERVAL",
    TIMEOUT = "TIMEOUT", 
 };

 interface TimerStateI {
   timeInterval: number;
 }

 interface TimerI: TimerStateI {
   type: string;
   autoStart: boolean;
 }

     class myTimer extends React.Component<TimerI, TimerStateI > {

          private myTimer: Tick = null;
          private myType: string = TIMER.INTERVAL;

          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);
            } else if (this.myType === TIMER.TIMEOUT) {
               this.myTimer = setTimeout(this.myTick, this.timeInterval);
            }



          }

     ...
     }

答案 4 :(得分:1)

我想这取决于您将在哪里运行代码。

如果您的运行时目标是服务器端Node JS,请使用:

let timeout: NodeJS.Timeout;
global.clearTimeout(timeout);

如果运行时目标是浏览器,请使用:

let timeout: number;
window.clearTimeout(timeout);

答案 5 :(得分:0)

我建议使用x: ReturnType<typeof setTimeout>;,因为它实际上可以独立于所使用的平台工作。

答案 6 :(得分:0)

NodeJS.Timeout似乎对我有用:

let timer: NodeJS.Timeout;
timer = setTimeout(console.log, 10);

我的tsconfig未配置compilerOptions,这是开箱即用的。

答案 7 :(得分:0)

如果您要定位QuerySet中的QuerySet。然后您也可以将其写为

Broker

答案 8 :(得分:0)

我通过设置解决了这个问题

tsconfig.json:
{
  "compilerOptions": {
    "skipLibCheck": true,
  }
}

并创建 .d.ts

*.d.ts:
declare namespace NodeJS {
    type Timeout = number;
    type Timer = number;
}

打字稿版本 4.2.3