【发布时间】:2016-03-15 06:48:33
【问题描述】:
我正在尝试将大型节点代码库迁移到 TypeScript。为方便起见,我只想从将 .js 文件重命名为 .ts 文件开始,修复任何语义问题,无需太多重构,然后逐步完善代码库。
让我们考虑以下示例:
logger.js:
exports = function(string) {
console.log(string);
}
moduleA.js:
var logger = require('./logger')
exports.someAction = function() {
logger.log('i'm in module a')
}
moduleB.js:
//var logger = require('./logger')
exports.someOtherAction = function() {
logger.log('i'm in module B')
}
moduleC.js:
var moduleA = require('./moduleA');
var moduleB = require('./moduleB');
exports.run = function(string) {
moduleA.someAction();
moduleB.someOtherAction(); //exception here - logger not defined
}
所以如果我执行 moduleB.someOtherAction() 我会得到一个异常,因为在 moduleB.js 的范围内没有定义记录器。
但是 typescript 编译得很好,因为 logger 是在 moduleA 中声明的,这是因为(如果我理解正确的话)typescript 将所有这些文件视为一个编译单元。
那么有没有办法避免这种情况而无需进行大量重构?
更新
我创建了一个示例项目which can be found here 如果我运行 typescript 编译器,我不会收到任何错误,尽管 logger 在 moduleB.ts 中被注释掉了:
g@w (master) ~/projects/ts-demo: gulp generate
[10:39:46] Using gulpfile ~/projects/ts-demo/gulpfile.js
[10:39:46] Starting 'generate'...
[10:39:46] Starting 'clean'...
[10:39:46] Finished 'clean' after 11 ms
[10:39:46] Starting '<anonymous>'...
[10:39:47] Finished '<anonymous>' after 1.4 s
[10:39:47] Finished 'generate' after 1.41 s
g@w (master) ~/projects/ts-demo:
更新 2
好的,这是TypeScript deep dive book 中所述的预期行为:
如果您现在在同一个项目中创建一个新文件 bar.ts,TypeScript 类型系统将允许您使用 foo.ts 中的变量 foo,就好像它是全局可用的一样
【问题讨论】:
-
这是不正确的。 Typescript 将每个文件视为一个单独的单元。 (声明文件除外)。 modelB 中
logger的值/类型是什么?将鼠标悬停在 IDE 上应该可以看到它。 -
它说 var logger: any。我创建了一个演示项目,请参阅更新的问题
-
“update 2”语句是正确的,但在定位节点时不是。它将以与节点相同的方式工作,即;每个文件都是它自己的“模块”,只有在正确导入的情况下才能在另一个文件中使用。
-
我更新了我的答案,你已经成功地为自己创造了一个有趣的案例。但它的根源在于,在为 commonjs 编译时,每个文件都是自己的封闭范围,因此您总是需要将一个文件导入另一个需要访问它的文件。
-
您缺少“模块”配置变量,因此 Typescript 将您的整个项目视为一个文件。检查我的答案。
标签: javascript node.js typescript