【问题标题】:What return type should be used for setTimeout in TypeScript?TypeScript 中的 setTimeout 应该使用什么返回类型?
【发布时间】:2018-12-05 01:06:33
【问题描述】:

考虑以下代码:

const timer: number = setTimeout(() => '', 1000);

Typescript 抛出错误:Type 'Timer' is not assignable to type 'number'. 快速查找告诉我 setTimeout 返回 NodeJS.Timer

但如果我在做基于浏览器的开发,使用NodeJS.Timer 感觉不对。在不诉诸any 声明的情况下,使setTimeout 工作的正确类型定义或返回类型是什么?

【问题讨论】:

标签: typescript


【解决方案1】:

最简单的解决方案是允许类型推断起作用并且根本不指定任何类型。如果需要指定类型,由于浏览器和节点声明的类型不一致,可以使用ReturnType 指定变量的类型是setTimeout 的返回类型是什么:

const timer: ReturnType<typeof setTimeout> = setTimeout(() => '', 1000);

或者,也可以使用window.setTimeout 而不仅仅是setTimeout。它返回正确的返回类型。

【讨论】:

  • 我尝试使用 window.setTimeout 而不是 setTimeout。 window.setTimeout 似乎返回数字作为类型。有什么我应该注意的区别吗?
  • 提香,如果可以的话,我会投票两次,祝福你!
  • 从 4.0.x 开始,如果您尝试将 setTimeout() 的返回类型传递给 clearTimeout(),TypeScript 将无法编译,因此需要强制转换为 number。这可能是 TypeScript 核心类型声明中的一个错误。
【解决方案2】:

你可以使用window.setTimeout它返回number的类型。

let a: number;
a = window.setTimeout(function() {}, 0);

【讨论】:

    【解决方案3】:

    这是因为 Typescript 会搜索 node_modules/@types 下的所有类型定义

    如果您将 NodeJS 类型定义(带有许多 npm 包)安装到 ~/node_modules/@types/node/globals.ts 并且您的项目位于 ~/Projects/myproject 中,则 setTimeout 的 NodeJS 定义将泄漏。

    默认情况下,所有可见的“@types”包都包含在您的 汇编。任何封闭文件夹的 node_modules/@types 中的包 被认为是可见的;具体来说,这意味着包内 ./node_modules/@types/, ../node_modules/@types/, ../../node_modules/@types/,等等。

    见:https://www.typescriptlang.org/tsconfig#types

    如果 Typescript 找到自定义类型定义,它的优先级高于默认类型定义。

    解决方案:

    • 指定 compilerOption 搜索类型定义的路径:"typeRoots":[]
    • 指定编译器选项从默认路径加载哪些类型定义:"types": []
    • 从默认搜索路径中删除定义文件
    • 改用window.setTimeout()

    【讨论】:

      【解决方案4】:

      window.setTimeout 返回number。理想情况下,您希望定义自己的类型以将其与数字区分开来(并防止像 + 这样对计时器没有意义的操作)。

      type TimerHandle = number;
      

      【讨论】:

      • 理论上是对的,但是TS是结构类型而不是普通类型。 type 只是创建一个别名。它仍然不会阻止。它。
      • 所有 Typescript 类型(如泛型等)只存在于编译时,在运行时你只有纯 Javascript,所以这对于你在 Typescript 中所做的几乎所有事情都是如此。
      • @Dmitry 你的帖子的问题是“防止像+ 这样的一些操作”——为number 定义类型别名不会阻止在编译时或运行时使用+ .您可以将两个TimerHandles 添加在一起,代码将编译并运行得很好。然而,有一些心理预防,因为人们可能会阅读该代码并认为他们有一些特殊的“TimerHandle”类型,而没有意识到它实际上只是一个数字。所以你的答案没有错,只是稍微误导了 IMO。
      【解决方案5】:

      对于其他遇到此错误的人来说,对我有用的是在 tsconfig.js 文件中添加:

      "compilerOptions": {
      
         ...
         "types": [],
      }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-11
        • 2020-06-24
        • 2021-01-20
        • 2013-08-12
        • 1970-01-01
        • 2021-07-06
        相关资源
        最近更新 更多