我有C++背景,在TypeScript方面有一天的经验。我正在尝试实现一个在多个文件之间分割的设计(接口/类(。它正在闪烁运行时错误:0x800a1391 - JavaScript runtime error: 'module' is not defined
Info.ts
export = Test; <----------- 0x800a1391 - JavaScript runtime error: 'module' is not defined
namespace Test {
export class Info {
}
}
TestWrapper.ts
import { Info } from "./Info";
namespace Test {
class TestWrapper {
public GetInfo(): Info {
return this.m_info;
}
}
}
我用错东西了吗?
猜测:
export = Something
编译为类似的内容
module.exports = Something
module.exports
是所谓的"commonjs模块系统"的一个构造,它在浏览器中不可用,但在node.js中可用。因此,如果您通过直接导入<script>
在浏览器中运行生成的代码,它将带来类似的错误。TS将imports
和exports
传输到可以在tsconfig.json中指定的模块系统,但TS本身不负责实现模块系统。
该怎么办?
如果这个代码真的应该在浏览器中运行,你可以选择以下两个选项之一:
- 通过模块bundler(webpack(运行代码,它将生成一个与浏览器兼容的"bundle"(一个大JS(,连接所有文件。Webpack有一些方法可以将typescript作为插件,这样你就不需要让你的"构建"过程分为两步;模块捆扎器通常相当复杂
- 减少文件模块(这意味着:没有顶级导入或导出(,并通过普通的
<script>
标签导入它们
我用错东西了吗?
虽然namespace
在其他语言中很常见,但它们在JavaScript中并不存在,因此typescript版本只是一些很少使用的方式,可以为某些内容添加正确的类型(我还从未使用过它(。在您的情况下,您实际上不需要名称空间。只是:
export default class Info { /*...*/ }
然后你可以
import Info from ".Info";
export default class TestWrapper { /*...*/ }
PS:也就是说,我实际上不知道如何使用名称空间来解决错误
看起来您正在尝试混合模块和名称空间。我建议阅读命名空间和模块。
您不需要使用export = Test
在顶级访问export
,也不应该使用import { Info } from "./Info";
,因为Info
是TestWrapper
所属的Test
命名空间的一部分。
如果你想走命名空间路线,可以考虑:
信息
namespace Test {
export class Info {}
}
TestWrapper.ts
namespace Test {
export class TestWrapper {
m_info: Info;
public GetInfo(): Info {
return this.m_info;
}
}
}
消费者
console.log(Test.TestWrapper);
使用编译
tsc --outFile foo.js Info.ts TestWrapper.ts Consumer.ts
然后使用运行
node foo.js
打印:
[Function: TestWrapper]