【问题标题】:Node.js with TypeScript: calling node.js function instead of standard带有 TypeScript 的 Node.js:调用 node.js 函数而不是标准函数
【发布时间】:2014-07-02 10:01:24
【问题描述】:

请帮我解决以下问题。 我使用 Visual Studio nodejs 工具创建了默认的 node.js 应用程序,现在我正在尝试调用在 node.d.ts 中声明的 setTimeout 函数。代码是这样的:

var timer: NodeTimer;
timer = setTimeout(somecallback, 1000);

但是代码没有编译说'Cannot convert 'Number' to 'NodeTimer''

据我了解,问题在于它采用标准的 setTimeout 函数,而不是从 node.d.ts 中获取。

我尝试使用 \\\<reference> 标签指定对 node.d.ts 的引用 - 这没有帮助。 如何明确声明我想使用 node.d.ts 中的 setTimeout?

【问题讨论】:

标签: javascript node.js typescript settimeout ntvs


【解决方案1】:

最简单的强制修复:

var timer: NodeTimer;
timer = <any>setTimeout(somecallback, 1000);

只是为了好玩

我根据当前节点定义 (https://github.com/borisyankov/DefinitelyTyped/blob/master/node/node.d.ts#L22) 创建了一个小样本,它在打字稿游乐场中运行良好

interface NodeTimer{
    ref() : void;
    unref() : void;
}
declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeTimer;

var timer: NodeTimer;
timer = setTimeout(()=>{}, 1000);

我不知道为什么你会在我没有的情况下发生冲突。仅供参考,lib.d.ts 中定义了冲突的 setTimeout,但它也包含在 TypeScript 操场中,不会引起任何戏剧性事件。

【讨论】:

  • 添加 真的很有帮助,谢谢!也许有人可以指出如何直接从节点引用 setTimeout
  • 我不认为TS Playground涉及node.js(至少它不会让你导入任何标准节点模块),所以那里没有冲突-它只有@987654326的定义@来自 lib.d.ts.
【解决方案2】:

我怀疑这被 TS 0.9.5 中引入的更改打破了,changelog 中将其描述为:

重载解析规则简化

说明:重载解析现在遵循更简单的算法。 当多个重载适合给定调用时,我们选择第一个适合的 而不是试图找到“最合适的”。

这意味着现在应该手动对具有重载的代码进行排序 最紧/更具体的重载到松散。

可用的两个重载如下:

// in lib.d.ts
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

// in node.d.ts
declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeTimer;

显然,第一个重载将始终匹配第二个可以匹配的所有内容,因此只要它是第一个考虑的重载,它将始终是首选。

在有两个 .d.ts 文件的情况下,就像这里一样,文件的顺序定义了它们重载的相对顺序。通常,lib.d.ts 总是排在第一位,因此它具有优先权。但是,如果您手动引用它,并确保引用在 node.d.ts 之后,那么后者将优先,您最终会得到正确的重载。

从命令行执行此操作很容易 - 只需按所需顺序明确指定 .d.ts 文件。对于 VS 项目,您可以对 _references.ts 执行相同操作,如下所示:

/// <reference path="Scripts/typings/node/node.d.ts" />
/// <reference path="C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\lib.d.ts" />

为避免像这样对绝对路径进行硬编码,您可能希望在项目中的 Scripts/typings/node 和 node.d.ts 旁边制作 lib.d.ts 的本地副本。

您可能还想在 TypeScript 论坛上通过 discussion thread 关注这一变化,并与 TS 团队分享您的经验。

【讨论】:

    【解决方案3】:

    如果您在尝试在 Browser »» Window 和 NodeJS 中使用 timeout 时遇到问题,例如 'Cannot convert 'Number' to 'NodeTimer'''Cannot convert 'Number' to 'NodeJS.Timer'''Cannot convert 'Number' to 'NodeJS.Timeout''Type 'Timeout' is not assignable to type 'number',您可以将这种类型安全的解决方案用于 Window 和NodeJS:

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

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 2018-03-19
      • 2018-10-13
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多