2016-07-28 896 views
2

我有节点程序,它最终使用commonjs,因此我的JS文件以需要语句开头。我改名这些JS文件TS,希望我能逐步进入打字稿,但我得到这些错误:无法重新声明块范围变量

enter image description here

从下面的代码:

const RSVP = require('rsvp'); 
const moment = require('moment'); 
const firebase = require('universal-firebase'); 
const email = require('universal-sendgrid'); 
const sms = require('universal-twilio'); 
const merge = require('merge'); 
const typeOf = require('type-of'); 
const promising = require('promising-help'); 
const _ = require('lodash'); 

const up = require('./upload'); 
const audience = require('./audiences'); 
const message = require('./messages'); 

的本地引用模块,如uploadaudiencesmessages很可能会定义大部分(全部?)相同的模块,如lodash等。我在猜测命名空间范围在某种程度上没有被尊重但是我不知道为什么。

我也不清楚是否使用ES6 import语法将适当transpile到ES5 CommonJS的“规定”模块格式(这是使用节点0.10.x)。

哦额外的背景下,我tsconfig.json是:

{ 
    "compilerOptions": { 
    "target": "es5", 
    "module": "commonjs", 
    "removeComments": true, 
    "sourceMap": true, 
    "outDir": "./dist", 
    "watch": true 
    }, 
    "compileOnSave": true 
} 

注:我见过其他人已经得到了“不能重新声明块范围的变量”错误之前,但没有交谈似乎真的完全适合我的情况。虽然我对打字稿很陌生,所以也许我会犯新手错误。


另外值得注意的是,我注意到CommonJS的和ECMAScript模块格式的奇特变异的一些例子:

import up = require('./upload'); 

这与如何我通常写为:

const up = require('./upload'); 

当我使用“导入”的关键字,但是,它抱怨说upload.ts是不是一个模块:

not a module

回答

2

如果我们看一下current snapshot of moment.d.ts on DefinitelyTyped,我们会看到,它是一个全球性的脚本文件(而不是一个模块)与命名moment变量:

declare var moment: moment.MomentStatic; 

它视为全球脚本文件,因为它不会导入或导出任何内容。

现在你的文件也是一个脚本文件。这听起来可能听起来不正确,但是这个想法是TypeScript不能单独识别require作为导入。 require技术上可以是任何其他功能。

相反,你需要使用特定的语法如下:

import moment = require("moment"); 

所有这一切确实是告诉打字稿,这是实际上进口,并且是安全而变换CommonJS的进口,AMD,UMD,SystemJS等


作为一个侧面说明,为打字稿2.0,我们已经更新了这些.d.ts文件是全球性的脚本文件,并在取而代之的是模块。如果你看到DefinitelyTyped的declaration files for moment in the types-2.0 branch,你可以看到下面几行:

declare var moment: moment.MomentStatic; 
export = moment; 

哪里export = moment是写module.exports = moment的模块系统无关的方式。

+0

我仍然对TS很感兴趣,所以我可能缺少突出点,但我不确定你对我的建议。我可能会补充说,“时间”似乎工作正常...... intellisense正在工作,没有编译错误。对于我正在操作的其他npm模块,这不是真的。 – ken

+0

@ken只有模块可以从其中导入,并且使文件成为模块的唯一方法是如果它具有某种类型的指示器,即它是模块。这包括导入,导出或'export = foo'语句。因此,如果你的文件没有被解析为模块,你需要*通过明确使用导出来使它们成为模块*。因此,而不是'module.exports.foo =函数(){}' 你会写 '导出函数foo(){}' 我的建议也把你的'常量富=要求(“富“)'调用使用'import foo = require(”foo“)'。 –

+0

哦,我明白了;是的,我的模块都在输出适当的功能。我最初使用的是node/commonjs语法,但已经开始使用ES6“导出”修改器。 – ken