Wie verwende ich Namespaces mit externen TypeScript-Modulen?
Ich habe einige code:
baseTypes.ts
export module Living.Things {
export class Animal {
move() { /* ... */ }
}
export class Plant {
photosynthesize() { /* ... */ }
}
}
Hund.ts
import b = require('./baseTypes');
export module Living.Things {
//Error, can't find name 'Animal', ??
export class Dog extends Animal {
woof() { }
}
}
Baum.ts
//Error, can't use the same name twice, ??
import b = require('./baseTypes');
import b = require('./dogs');
module Living.Things {
//Why do I have to write b.Living.Things.Plant instead of b.Plant??
class Tree extends b.Living.Things.Plant {
}
}
Dies ist alles sehr verwirrend. Ich möchte eine Reihe externer Module tragen alle Typen mit den gleichen namespace Living.Things
. Es scheint, dass dies überhaupt nicht funktioniert-ich kann nicht sehen Animal
im dogs.ts
. Ich habe das schreiben der vollständige namespace-name b.Living.Things.Plant
im tree.ts
. Es funktioniert nicht, mehrere Objekte kombinieren im gleichen namespace in die Datei. Wie mache ich das?
InformationsquelleAutor der Frage Ryan Cavanaugh | 2015-05-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Candy Cup Analogie
Version 1: Eine Tasse für jede candy
Lassen Sie uns sagen Sie, dass Sie schrieb einige code wie folgt:
Mod1.ts
Mod2.ts
Mod3 ein;.ts
Die Sie erstellt haben und dieses setup:
Jedes Modul (Blatt Papier) wird seine eigene Tasse namens
A
. Das ist sinnlos - du bist nicht wirklich die Organisation Ihre Süßigkeit hier, du bist nur das hinzufügen einer zusätzlichen Schritt (Entnahme aus der Tasse) sich zwischen Sie und die leckereien.Version 2: Eine Tasse, die im globalen Gültigkeitsbereich
Wenn du nicht mit Modulen, könnten Sie code schreiben (beachten Sie das fehlen von
export
Erklärungen):global1.ts
global2.ts
global3.ts
Diese code erstellt eine zusammengeführte namespace
A
im globalen Gültigkeitsbereich:Diese Einstellung ist sinnvoll, aber nicht in dem Fall, daß die Module (da-Module verschmutzen nicht die Umwelt im globalen Gültigkeitsbereich).
Version 3: cupless
Geht zurück auf das ursprüngliche Beispiel, die Tassen
A
,A
, undA
nicht tun Sie keinen gefallen. Stattdessen könnte man den code schreiben als:Mod1.ts
Mod2.ts
Mod3 ein;.ts
erstellen ein Bild, das aussieht wie dieses:
Viel besser!
Nun, wenn Sie denken immer noch darüber, wie viel Sie wirklich verwenden wollen-namespace mit Ihren Modulen, Lesen Sie weiter...
Diese Sind nicht die Konzepte, die Sie Suchen
Wir müssen zurück zu den Ursprüngen, warum namespaces existieren, an Erster Stelle und prüfen, ob diese Gründe machen Sinn für externe Module.
Organisation: Namespaces sind praktisch für die Gruppierung von logisch zusammengehörigen Objekten und Typen. Zum Beispiel in C#, du wirst finden, alle Sammlungen in
System.Collections
. Durch die Organisation unserer Arten in hierarchische Namensräume, wir bieten einen guten "discovery" - Erfahrung für die Nutzer dieser Typen.Namenskonflikte: Namespaces sind wichtig, um zu vermeiden Namenskonflikte. Zum Beispiel, haben Sie vielleicht
My.Application.Customer.AddForm
undMy.Application.Order.AddForm
-- zwei Typen mit dem gleichen Namen, aber einem unterschiedlichen namespace. In einer Sprache, wo alle Bezeichner existieren in der gleichen root-scope und alle Assemblys laden alle Typen, es ist wichtig zu haben alles in einem namespace.Diese Gründe machen Sinn in externen Modulen?
Organisation: Externe Module sind bereits in einem Dateisystem, unbedingt. Wir haben Sie zu lösen, indem Sie den Pfad und den Dateinamen, so dass es eine logische Organisation Schema für uns zu nutzen. Wir haben eine
/collections/generic/
Ordner mit einemlist
module.Namenskonflikte: Dies gilt nicht an alle, die in externen Modulen. Innerhalb ein Modul, es gibt keinen plausiblen Grund zu haben, zwei Objekte mit dem gleichen Namen. Von der Konsum-Seite, die Verbraucher von einem bestimmten Modul wird um die Namen, die Sie verwenden, um beziehen sich auf das Modul, so dass unbeabsichtigte Kollisionen sind unmöglich.
Selbst wenn Sie nicht glauben, dass diese Gründe ausreichend angesprochen werden, wie Module funktionieren, die "Lösung" zu versuchen, die Verwendung von namespaces in externe Module gar nicht funktionieren.
Kisten in Kisten in Kisten
Geschichte:
Module Ihre Eigene Box
Haben Sie wahrscheinlich hatte etwas ähnliches passieren im wirklichen Leben: Sie bestellen ein paar Sachen auf Amazon, und jedes Element zeigt sich in seiner eigenen box, eine kleinere box im inneren, mit Ihrem Einzelteil eingewickelt in seiner eigenen Verpackung. Auch wenn die inneren Boxen sind ähnlich, die Sendungen sind nicht sinnvoll "kombiniert".
Gehen mit der box-Analogie, der Schlüssel ist die Beobachtung, dass externe Module sind eigene box. Es könnte sein, ein sehr Komplexes Element mit vielen Funktion, kann aber beliebige externe Modul ist eine eigene box.
Anleitung für Externe Module
Nun, dass wir herausgefunden haben, dass wir nicht brauchen, um verwenden 'namespaces', wie sollten wir uns organisieren, unsere Module? Einige Leitprinzipien und Beispiele Folgen.
Exportieren, als in der Nähe von top-level wie möglich
export default
:MyClass.ts
MyFunc.ts
Verbrauch
Ist dies optimal für den Verbraucher. Sie können den Namen Ihr geben, was Sie wollen (
t
in diesem Fall) und nicht zu tun haben, alle überflüssigen Punktierung, Ihre Objekte zu finden.MyThings.ts
Verbrauch
module
/namespace
Stichwort:MyLargeModule.ts
Verbrauch
Roten Fahnen
Alle der folgenden sind rote Fahnen für das Modul strukturieren. Überprüfen Sie, dass Sie nicht versuchen, um namespace-Ihre externe Module, wenn diese für Ihre Dateien:
export module Foo { ... }
(entfernenFoo
und alles bewegen, was " up " eine Ebene)export class
oderexport function
dass nichtexport default
export module Foo {
im top-level (glaube nicht, dass diese gehen, um zu einem zu vereinenFoo
!)InformationsquelleAutor der Antwort Ryan Cavanaugh
Nichts falsch mit Ryans Antwort, aber für die Leute, die kamen hier auf der Suche für how, um eine eine Klasse pro Datei Struktur, während immer noch mit ES6-namespaces korrekt entnehmen Sie bitte diese hilfreiche Ressource von Microsoft.
Eins ist mir unklar nach Lesen der doc ist: so importieren Sie die gesamte (zusammengeführt) - Modul mit einem single
import
.Bearbeiten
Kreisen zurück zu aktualisieren diese Antwort. Einige Ansätze zur Verwendung von Namensräumen erscheinen im TS.
Alle Modul-Klassen in einer Datei.
Importieren von Dateien in namespace, und weisen
Fässer
Eine abschließende überlegung. Sie könnte namespace jede Datei
Aber wie man importiert zwei Klassen im gleichen namespace TS beschweren, es gibt eine doppelte Bezeichner. Die einzige Lösung, da dies die Zeit ist, um dann die namespace-alias.
Dieses aliasing ist absolut abscheulich, so tun Sie es nicht. Du bist besser dran mit einem Ansatz oben. Ich persönlich bevorzuge die 'barrel'.
InformationsquelleAutor der Antwort Jefftopia
Versuchen Sie zu organisieren, indem Sie Ordner:
baseTypes.ts
Hund.ts
Baum.ts
LivingThings.ts
main.ts
Die Idee ist, dass das Modul selbst sollte sich keine Gedanken /wissen, dass Sie beteiligt sind in einem namespace, aber dies macht Ihre API, um den Verbraucher in eine kompakte, sinnvolle Weise, die nicht wissen, welche Art von Modul-system, das Sie verwenden für das Projekt.
InformationsquelleAutor der Antwort Albinofrenchy
Kleine impovement von Albinofrenchy Antwort:
Basis.ts
Hund.ts
Dinge.ts
main.ts
InformationsquelleAutor der Antwort Mike Vitik
OP bin ich mit Ihnen der Mensch.
wieder zu, es ist nichts falsch mit, dass die Antwort mit 300+ up Stimmen, aber meine Meinung ist:
was ist falsch mit putting-Klassen in Ihrem gemütlichen, warmen eigene Dateien einzeln?
Ich meine, das macht die Sache sieht viel besser aus, richtig? (oder jemand, den Sie einfach wie ein 1000-Linien-Datei für alle Modelle)
also dann, wenn der erste erreicht wird, müssen wir importieren, importieren, importieren, importieren... nur in jedem der Modell-Dateien, wie der Mensch, srsly, ein Modell-Datei, eine .d....ts-Datei, warum es so viele *s? es sollte einfach sein, einfach, sauber, und das ist es. Warum brauche ich den Einfuhren gibt es? warum? C# habe namespaces für einen Grund.
Dann sind Sie buchstäblich mit "Dateinamen.ts" als Bezeichner. Als Bezeichner... Kommen auf seinen 2017 jetzt, und wir das noch machen? Ima gehen Sie zurück zu Mars und schlafen für weitere 1000 Jahre.
So traurig, meine Antwort ist: nop, Sie nicht den "namespace" Ding funktionsfähig, wenn Sie nicht mit allen jenen, die Einfuhr oder die Verwendung dieser Dateinamen als id (die ich denke, ist wirklich dumm). Eine weitere option ist: alle diese Abhängigkeiten in einer box namens filenameasidentifier.ts und Einsatz
wickeln Sie Sie, damit Sie nicht versuchen, auf anderen Klassen mit gleichen Namen, wenn Sie einfach nur versuchen, einen Verweis aus der Klasse sitzen direkt an der Oberseite von Ihnen.
InformationsquelleAutor der Antwort NO... Bugs...
Mehrere der Fragen/Kommentare, die ich gesehen habe, um dieses Thema Klang für mich so, als ob die person
Namespace
wo meinen Sie 'Modul-alias'. Als Ryan Cavanaugh erwähnt in einem seiner Kommentare, die Sie haben können, eine "Wrapper" - Modul re-exportieren Sie mehrere Module.Wenn Sie wirklich wollen, um es zu importieren alle aus dem gleichen Modul-Namen/alias, verbinden Sie ein wrapper-Modul mit einer mapping-Pfade in Ihrer
tsconfig.json
.Beispiel:
./path/to/CompanyName.Products/Foo.ts
./path/to/CompanyName.Products/Bar.ts
./path/to/CompanyName.Products/index.ts
tsconfig.json
main.ts
Hinweis: Das Modul Auflösung in der Ausgabe .js-Dateien gehandhabt werden müssen irgendwie, wie mit diesem https://github.com/tleunen/babel-plugin-module-resolver
Beispiel
.babelrc
Griff der alias-Auflösung:InformationsquelleAutor der Antwort Ryan Thomas
Hund.ts
Baum.ts
InformationsquelleAutor der Antwort Alessandro Lendaro
Necromancing.
Wenn ich verstehe richtig, Sie Fragen sich, wie Sie haben alle Ihre Klassen in eine separate Datei unter Beibehaltung einer einzigen namespace für Sie alle.
Da niemand zu haben scheint eine gute Lösung - hier ist eine Idee für eine einfache Lösung, gar nicht einbeziehen Typoskript: die Lösung heißt Schluck.
Setzen Sie einfach alle Ihre Klassen werden müssen in einem Namensraum liegen in den gleichen Ordner (nützlich für code-organisation sowieso). Dann fügen Sie eine Schluck-Aufgabe, werden alle Dateien in diesem Verzeichnis in einer Datei (gulp-concat). Dann, fügen Sie einen namespace mit dem selben Namen wie das top-Verzeichnis, fügen Sie die verketteten Dateien, fügen Sie eine schließende Klammer ein, und speichern Sie in einer Datei.
Getan.
Dann fügen Sie eine Schluck-Aufgabe, die Uhren für änderungen (Zugänge/Abgänge) im gleichen Verzeichnis. Auf ändern/hinzufügen, auslösen die concat-Funktion.
Nun müssen Sie alle Klassen in eine Datei, und eine Datei, die enthält alle Klassen in einem namespace.
Beispiel für code - entlang der Linien von:
Gibt ' s einen Schluck append-anfügen-Modul hier:
https://www.npmjs.com/package/gulp-append-prepend
Schließlich, legen Sie die watcher beginnen, auf der Lösung legen, und du bist fertig.
InformationsquelleAutor der Antwort Stefan Steiger