Cannot redeclare block-scoped variable
If we look at the current snapshot of moment.d.ts
on DefinitelyTyped, we'll see that it is a global script file (as opposed to a module) with a variable named moment
:
declare var moment: moment.MomentStatic;
It's considered a global script file because it doesn't import or export anything.
Right now your file is also a script file. That might not sound correct, but the idea is that TypeScript doesn't recognize require
on its own as an import. require
could technically be any other function.
Instead, you'll need to use a specific syntax for this:
import moment = require("moment");
All that does is tell TypeScript that this is actually an import, and is safe to transform into an import in CommonJS, AMD, UMD, SystemJS etc.
As a side note, for TypeScript 2.0, we've updated these .d.ts
files not to be global script files, and instead be authored as modules. If you see the declaration files for moment in the types-2.0
branch in DefinitelyTyped, you can see the following lines:
declare var moment: moment.MomentStatic;
export = moment;
Where export = moment
is module system-agnostic way of writing module.exports = moment
.
ken
An "older developer" who got out of coding and into senior management but has decided to come back out of the clouds and get dirty again with code. Happy days. :^)
Updated on June 30, 2022Comments
-
ken almost 2 years
I have node program which ultimately uses commonjs and therefore my JS files start with a number of require statements. I renamed these JS files to TS with the hope that I could incrementally move into Typescript but am getting these errors:
from the following code:
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');
The locally referenced modules like
upload
,audiences
, andmessages
are likely to define most (all?) of the same modules suchlodash
, etc. I'm guessing that somehow the namespace scope is not being respected between modules but I'm not sure why.I'm also unclear whether using ES6
import
syntax would properly transpile to a ES5 commonjs "require" module format (this is using Node 0.10.x).Oh as additional context, my
tsconfig.json
is:{ "compilerOptions": { "target": "es5", "module": "commonjs", "removeComments": true, "sourceMap": true, "outDir": "./dist", "watch": true }, "compileOnSave": true }
Note: I've seen other people have gotten the "cannot redeclare block-scoped variable" error before but none of the conversations seemed to really fully fit my situation. Although i'm quite new to Typescript so maybe I'm making a newbie mistake.
Also of note, I noticed some examples of a strange variant of commonjs and ecmascript module formats:
import up = require('./upload');
This is in contrast to how I'd normally write it as:
const up = require('./upload');
When I use the "import" keyword, however, it complains that
upload.ts
is not a module: