如何在没有类型定义的情况下导入Typescript中的节点模块?

cze*_*rny 10 node.js typescript

当我尝试在Typescript中导入node.js模块时,如下所示:

import co = require('co');
import co from 'co';
Run Code Online (Sandbox Code Playgroud)

如果没有提供类型定义,两行都报告相同的错误:

error TS2307: Cannot find module 'co'.
Run Code Online (Sandbox Code Playgroud)

如何正确导入?

cze*_*rny 9

诀窍是使用纯 JavaScript 符号:

const co = require('co');
Run Code Online (Sandbox Code Playgroud)


Tim*_*rry 8

您可以选择在TypeScript的模块系统外部导入它(通过直接手动调用RequireJS或Node等模块API),这样它就不会尝试验证它,或添加类型定义以便您可以使用模块系统并让它正确验证.您可以存储类型定义,因此这可能非常省力.

使用Node(CommonJS)直接导入:

// Note there's no 'import' statement here.
var loadedModule: any = require('module-name');

// Now use your module however you'd like.
Run Code Online (Sandbox Code Playgroud)

直接使用RequireJS:

define(["module-name"], function (loadedModule: any) {
    // Use loadedModule however you'd like
});
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,这可能会与在同一文件中使用真正的普通TypeScript模块导入混合在一起(最终可能会有两层模块定义,尤其是在RequireJS端,因为TypeScript会尝试管理模块.也是手工管理).我建议使用这种方法,或使用真实的类型定义.

存根类型定义:

获得正确的类型定义将是最好的,如果这些是可用的或你有时间自己编写它们你应该应该.

如果没有,你可以给你的整个模块any类型,并将你的模块放入模块系统而不必实际输入:

declare module 'module-name' {
    export = <any> {};
}
Run Code Online (Sandbox Code Playgroud)

这应该允许您导入module-name并让TypeScript知道您在说什么.您仍然需要确保导入模块名称确实在运行时使用您正在使用的任何模块系统成功加载它,否则它将编译但无法实际运行.


dan*_*nvk 5

当我在 Tim Perry 的答案中使用“存根类型定义”方法时,出现错误:error TS2497: Module ''module-name'' resolves to a non-module entity and cannot be imported using this construct.

解决方案是稍微修改存根.d.ts文件:

declare module 'module-name' {
  const x: any;
  export = x;
}
Run Code Online (Sandbox Code Playgroud)

然后您可以通过以下方式导入:

import * as moduleName from 'module-name';
Run Code Online (Sandbox Code Playgroud)

创建您自己的存根文件可以降低根据需要编写实际声明的障碍。