Sie sind nicht-Module verwenden. Module verfügen über eine oder mehrere Top-Level-Anweisungen import
oder export
. Stattdessen verwenden Sie den globalen Namespace und erstellen Unternamespaces des globalen Namespace, um Ihr Programm zu organisieren. Dies wird das aufschlussreiche Modulmuster genannt. Es beinhaltet nicht die Verwendung von Modulen.
Leider verwendete TypeScript dieses Muster als Internal Modules. Diese Terminologie ist seither veraltet und die Verwendung der module x {}
Syntax (beachten Sie das Fehlen von "
s um x
) wird dringend davon abgeraten. Die Sprache hat auch ein Stichwort eingeführt namespace
, um die Verwirrung zu reduzieren.
JavaScript-Loader und -Bundler wie Webpack, RequireJS und SystemJS arbeiten mit Modulen, was TypeScript als externe Module bezeichnet.
folgende Konstrukte Um zu klären, die Sie erwähnen, sind nicht Modul
Zusammenhang
Top-Level nicht ausgeführten module
/namespace
syntaktischen Erklärungen
module vi.input.header { ... }
dies nun als
geschrieben werden würde namespace vi.input.header { ... }
, um Verwirrung zu minimieren, aber irregardless hat die emit immer in Folge.
var vi;
(function (vi) {
var input;
(function (input) {
var header;
(function (header) {
})(header = input.header || (input.header = {}));
})(input = vi.input || (vi.input = {}));
})(vi || (vi = {}));
Hinweis: dieser mutiert die globale Reichweite in einem Muster von verschiedenen Bibliotheken verwendet. namespace
s (früher interne Module genannt) wie die oben genannte haben die interessante Eigenschaft, dass mehrere Dateien zu ihren Inhalten beitragen können, und dies ist in der Tat ihr Hauptzweck. Dies erklärt den Grad der Verschachtelung und die bedingten Zuordnungen zu Variablen in der obigen Ausgabe. Dies hat nichts zu tun mit Module.
import
Zuordnungen, die namespace
Mitglieder wie
import IDirective = angular.IDirective;
gelten nicht als Top-Level-import
Erklärungen, und somit führen nicht ihre enthalten Datei ein Modul betrachtet werden verweisen. Dies gilt auch dann, wenn sie auf der obersten Ebene einer Datei stehen. Der Grund ist, dass Modulsysteme, seien es AMD, CommonJS, System oder ES2015, alle Strings als Modulspezifizierer verwenden, die aus solchen Strings importieren; welches übrigens Dateipfade, URLs, aufgelöste einfache Namen oder synthetische Modul-IDs darstellen kann.
Auch hier sind die import name = qualified.global.name
Aussagen in Ihren Code ein Typoskript spezifische Funktion, die zu Module ohne Bezug ist. Sie können sehr nützlich für Aliasing geschachtelte Typen und Werte sein, aber Module, die sie nicht machen.
Hier ist, wo es interessant wird, und wo es mit Ihrer spezifischen Frage namespace
s schneidet kann verwendet werden, und manchmal recht elegant, von innerhalbexternen Module, aber ihre Semantik ist sehr unterschiedlich
Betrachten
Dienstleistungen.ts
export namespace app {
export class SomeService { }
}
die in die folgenden JavaScript
export var app;
(function (app) {
class SomeService {
}
app.SomeService = SomeService;
})(app || (app = {}));
main.ts
export namespace app {
export function bootstrap() { }
}
die sich in folgende JavaScript
export var app;
(function (app) {
function bootstrap() { }
app.bootstrap = bootstrap;
})(app || (app = {}));
kompiliert kompiliert
Sowohl oberhalb von externen Modulen sind, das ist wahr Module, dass die Verwendung von Namespaces als interne Code Organisation Mechanismen aber sie Schlüssel zum Mitnehmen ist, dass sie nicht tun zu einem Sharedapp
Namespace beisteuern, die jeweils ihre eigenen mit, Datei scoped app
Variable. Weder hat impliziten Zugriff auf die Mitglieder des anderen, die Deklarationen von namespace app
verschmelzen nicht über Dateien, und sie haben ein ähnliches internes Benennungsschema ist neben ihrer Modularität.
Wie hängt das alles von Ihrer Frage und den Vorschlägen ab, die Sie anwenden wollten?
uns kein Modul ist
headers.ts
module vi.input.header {
import IDirective = angular.IDirective;
export class VIInputDirective implements IDirective {
static whatever() { }
}
}
Diese Datei Mal sehen, wie oben erläutert, und verwendet den globalen Namespace seine Erklärungen zu belichten. Wenn wir dies heute schreiben würden, würden wir das Schlüsselwort namespace
anstelle des Schlüsselwortes module
per Konvention verwenden.
main.ts
import {VIInputDirective} from "./header.ts"; // Nothing imported; Cannot Resolve issue
VIInputDirective.whatever(); // Does not work
Tatsächlich funktioniert weder Linie, weil Sie headers.ts importieren, als ob es sich um ein Modul waren, aber wie wir es gerade ist ein Modul nicht gesehen haben. Darüber hinaus macht die erste Zeile, die eine import
Anweisung der obersten Ebene ist, die aus einer Modulspezifikationszeichenfolge importiert, ironischerweise main.ts, ein Modul.
Kurz gesagt, die zwei Stile nicht gut mischen, und das Teilen von Code zwischen ihnen ist nicht einfach und ist nicht etwas, was Sie wahrscheinlich versuchen sollten (Ich habe das UMD-Format aus dieser Antwort zu versuchen, es relativ einfach zu halten).
Jetzt schließt sich der Kreis
starken Text
declare module vi.input {
....
}
If I swap import {VIInputDirective} from "./header.ts"; in the main.ts file with import VIMHeaderDirective = vi.input.header.VIInputDirective; it works fine, but then webpack on transpile/inject gives me the following error:
der Tat, wie oben erläutert. Diese import
, die nicht auf eine Modulspezifikationszeichenfolge abzielt und keine anderen Importe oder Exporte auf oberster Ebene enthält, ändert main.ts so, dass es kein Modul mehr ist.Dies bewirkt, dass TypeScript es korrekt schreibt. Globale Variablen, die sich gegenseitig referenzieren, sind import = namespace.value
vollkommen legitim, aber dies sind keine Module und JavaScript-Tools, wie z. B. Webpack, funktionieren auf Modulen.
Also, wie würdest du diese App in dieser schönen neuen Welt schreiben? Da Sie ein Modulpaket-Tool, Webpack, verwenden, würden Sie es mit den richtigen Modulen schreiben.
main.ts
import {VIInputDirective} from "./header.ts";
VIInputDirective.whatever();
headers.ts
import {IDirective} from 'angular';
export class VIInputDirective implements IDirective {
static whatever() { }
}
material.d.ts sieht nicht mehr wie damals, als Sie dies schrieb, wie es gewesen ist aktualisiert, um mit den richtigen Modulen zu arbeiten. Wenn Sie etwas von ihm verweisen müssen, verwenden Sie das Modul Syntax
my-Dialog-options.ts
import {material} from 'angular';
const dialogOptions: material.IDialogOptions = { ... };
export default dialogOptions;
ich versucht habe, nicht zu sehr zu vereinfachen, aber einige Handbewegung, die zur Vermeidung war ein Schreiben Novelle zu dem Thema, aber ich glaube, ich hoffe, die wichtigsten Punkte abgedeckt und vermittelt haben.
Haben Sie versucht, importieren * als x von "./header" dann neue x.vi.input.header.VIInputDirective – Banners
Vielleicht sollten Sie auch versuchen, eine Exportanweisung zu der Moduldeklaration hinzufügen (jetzt in 'Namespace' in geändert Typoskript) – Banners
Probieren Sie dies "Import * als VIInputDirective von" ./header.ts "und TypeScript ist nicht in der Lage, das Modul zu finden. Ich bekomme den Fehler Canlist Resolve File. Wenn ich nicht header.ts in ein Modul einpacken (ie Modul vi.input.header {}), es funktioniert gut, aber ich möchte das behalten. – sags