2016-07-28 11 views
2

nicht redeclare Ich habe Knotenprogramm, das schließlich commonjs verwendet und daher beginnen meine JS-Dateien mit einer Anzahl von erfordern Anweisungen. Ich benannte diese JS-Dateien in TS mit der Hoffnung, dass ich schrittweise in Typoskript bewegen könnte, aber ich immer diese Fehler:Kann Block-Bereichsvariable

enter image description here

aus dem folgenden 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'); 

Die lokal referenzierten Module wie upload , audiences und messagessind wahrscheinlich die meisten (alle?) Der gleichen Module wie lodash usw. zu definieren. Ich vermute, dass irgendwie der Namespace-Bereich zwischen mo nicht respektiert wird Aber ich weiß nicht warum.

Ich bin auch unklar, ob ES6 import Syntax richtig ein ES5 Commonjs "require" Modulformat (dies wird mit Knoten 0.10.x) transpile würde.

Oh als zusätzlicher Kontext, mein tsconfig.json ist:

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

Hinweis: Ich habe andere Leute haben die „neu deklarieren kann nicht block scoped Variable“ Fehler bekommen gesehen vor, aber keines der Gespräche schien wirklich meiner Situation zu entsprechen. Obwohl ich in Typescript ziemlich neu bin, mache ich vielleicht einen Anfänger Fehler.


Auch der Hinweis, bemerkte ich einige Beispiele für eine seltsame Variante von Commonjs und ecmascript Modulformate:

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

Dies steht im Gegensatz zu, wie ich es normalerweise schreiben würde wie:

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

Als ich den „Import“ Schlüsselwort verwenden, jedoch wirft sie upload.ts kein Modul ist:

not a module

Antwort

2

Wenn wir die current snapshot of moment.d.ts on DefinitelyTyped sehen, wir werden sehen, dass es eine globale Skriptdatei (zu einem Modul im Gegensatz) ist mit einem variablen moment genannt:

declare var moment: moment.MomentStatic; 

Es ist ein global betrachtet hat Skriptdatei, da nichts importiert oder exportiert wird.

Jetzt Ihre Datei ist auch eine Skriptdatei. Das klingt vielleicht nicht korrekt, aber die Idee ist, dass TypeScript require nicht selbst als Import erkennt. require könnte technisch jede andere Funktion sein.

Stattdessen müssen Sie eine bestimmte Syntax für diesen Einsatz:

import moment = require("moment"); 

Alles, was tut, ist Typoskript sagen, dass dies tatsächlich ein Import, und ist sicher in einem Import in Commonjs zu verwandeln , AMD, UMD, SystemJS usw.


Als Randbemerkung, für Typoskript 2.0 haben wir diese .d.ts Dateien nicht sein globales Skriptdateien aktualisiert, und in statt als Module erstellt werden. Wenn Sie die declaration files for moment in the types-2.0 branch in DefinitelyTyped sehen, können Sie die folgenden Zeilen sehen:

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

Wo export = moment ist Modulsystem-unabhängige Weise module.exports = moment zu schreiben.

+0

Ich bekomme immer noch meinen Kopf um TS, so dass ich wichtige Punkte vermisse, aber ich bin mir nicht sicher, was Sie für mich vorschlagen. Ich könnte hinzufügen, dass "Moment" scheint wirklich gut zu funktionieren ... intellisense funktioniert und keine Kompilierungsfehler. Dies gilt nicht für andere npm-Module, auf denen ich arbeite. – ken

+0

@ken Nur Module können importiert werden, und die einzige Sache, die eine Datei zu einem Modul macht, ist, wenn sie irgendeine Art von Indikator hat, dass es ein Modul ist. Dazu gehören Importe, Exporte oder eine "export = foo" -Anweisung. Wenn also Ihre Dateien nicht als Module aufgelöst werden, müssen Sie * Module * erstellen, indem Sie explizit Exporte verwenden. So anstelle von 'module.exports.foo = function() {}' Sie würden schreiben 'Exportfunktion foo() {}' Mein Vorschlag ist auch Ihre 'const foo = require (" foo zu drehen ")' ruft auf, um 'import foo = require (" foo ")' zu verwenden. –

+0

Oh ich sehe; Ja, meine Module exportieren alle die entsprechenden Funktionen. Ich habe ursprünglich die Syntax "node/commonjs" verwendet, habe aber begonnen, den ES6-Modifikator "export" zu verwenden. – ken