2012-11-21 11 views
43

Ich bin daran interessiert, ein existierendes Framework (openlayers.d.ts) zu definieren, kann aber nicht herausfinden, wie ich die Tatsache ausdrücken kann, dass OpenLayers.Layer sowohl eine Klasse als auch ein Namespace für OpenLayers.Layer.Markers ist. Ich glaube, das macht Marker zu einer verschachtelten Schichtklasse.Gibt es eine Möglichkeit, eine Nest-Klassenstruktur in Typoskript zu deklarieren?

Nutzung:

l = new OpenLayers.Layer(...); // this is a base class, never do this 
m = new OpenLayers.Layer.Markers(...); 

Wie würden Sie erklären sowohl die Layer-und Marker-Klasse in Typoskript?

+0

Dies scheint unter http ein Duplikat der offenen Frage zu sein://Paketüberfluss.com/questions/12799433/typescript-modul-und-class-simultan –

+2

Nicht darüber reden, wie Sie dies aus einer * Deklaration * Perspektive modellieren möchten, aber TypeScript hat nun geschachtelte Klassenunterstützung: http://StackOverflow.com/a/32494175/390330 – basarat

Antwort

50

Dies scheint in den Versionen 0.9.1.1 und höher behoben worden zu sein. Sie müssen nur ein Modul mit demselben Namen wie die Klasse erstellen, in der Sie Typen verschachteln möchten, und Ihre verschachtelten Typen darin einfügen.

Konkreter, das ist, wie Sie es tun:

declare module a 
{ 
    class b 
    { 
    } 

    module b 
    { 
     class c 
     { 
     } 
    } 
} 

var myB = new a.b(); 
var myC = new a.b.c(); 

Dies funktioniert auch, wenn Typen in Typoskript Code mit dem Export Stichwort nisten:

export module a 
{ 
    export class b 
    { 
    } 

    export module b 
    { 
     export enum c 
     { 
      C1 = 1, 
      C2 = 2, 
      C3 = 3, 
     } 
    } 
} 

Wie vom Benutzer @recursive erwähnt In den Kommentaren unten ist die Reihenfolge der Deklaration wichtig. Die Klassendefinition muss also vor dem Modul mit den verschachtelten Typen liegen.

+7

Ich konnte das nicht zur Arbeit bringen, aber dann wurde mir klar, dass die Reihenfolge wichtig ist. Dies scheint nur zu funktionieren, wenn Sie zuerst die Klasse und dann das Modul deklarieren. Es funktioniert nicht umgekehrt. – recursive

+0

Wie machst du das mit einem Angular-Projekt mit Typescript? Module verwenden den Dekorator: @NgModule –

12

Sie können Zusammenführen verwenden Modul mit gleicher Wirkung wie verschachtelte Klassen zu erhalten. Dieses Beispiel wurde aus Kapitel 1 von Pro TypeScript übernommen.

Sie führen das Zusammenführen von Modulen mit einer Klasse und einem Modul oder mit einer Funktion und einem Modul durch.

In all cases, the module must appear after the class or function for the merge to work.

Angepasst Beispiel:

class Outer { 

} 

module Outer { 
    export class Mid { 

    } 

    export module Mid { 
     export class Inner { 

     } 
    } 
} 

var a = new Outer(); 
var b = new Outer.Mid(); 
var x = new Outer.Mid.Inner(); 

Original-Antwort

Hinweis: diese ursprüngliche Antwort (im Jahr 2012 veröffentlicht), die auf Version 0.8 von Typoskript.

Sie können immer noch eine Deklaration erstellen, die die von Ihnen beschriebenen Verwendungen zulässt, nur dass das Objekt Markers vom Typ any ist. Dies kann verbessert werden, wenn das Workitem der geschachtelten Klasse repariert ist.

+0

wie Methode von Mid-Klasse zu Outer-Klasse aufrufen? – cracker

6

Dies ist ein bisschen spät, aber andere können es nützlich finden. So habe ich es gemacht, TS zu täuschen, um die Aufgabe zu erfüllen.

declare module OpenLayers { 
    interface Layer { 
    .... 
    } 

    interface Markers { 
    .... 
    } 

    var Layer: { 
    new(name:string, options?:any):Layer; 
    prototype:Layer; 
    Markers: { 
     new(params?:any):Markers; 
     prototype: Markers; 
    } 
    } 
} 

var markers = new OpenLayers.Layer.Markers(); 
+0

Das hat mein Problem gelöst – nkint

+0

Wie können Sie eine Variable namens Layer im gleichen Bereich wie eine Schnittstelle namens Layer haben? – CodyBugstein

8

Ab 2016 Ich denke, das ist einfacher:

class A { 
    static B = class { } 
} 

var a = new A(); 
var b = new A.B(); 
+2

Ich bekomme diesen Kompilierfehler 'Initialisierer sind nicht erlaubt in Ambient-Kontexten 'mit Atom Latest Ts Plugin – nkint

+0

Wie können Sie beziehen sich auf das' This' von 'A' innerhalb einer Methode von' B' ohne zu übergeben es als Argument explizit? Oder ist das unmöglich, da "B" statisch ist? Meine derzeitige Lösung besteht darin, eine "bFactory" -Methode auf 'A' zu haben, wo ich explizit auf' A'-Member zugreifen und sie an den 'B'-Konstruktor übergeben kann, aber ich hatte gehofft, dass es einen besseren Weg dafür gibt. – Monkpit

+0

@Monkpit: 'this' bezieht sich auf ein' a'-Objekt und nicht auf die 'A'-Klasse. Sie können viele 'a's und viele' b's instanziieren, jedes mit seinem eigenen 'this'. Wie könnte also ein bestimmtes "b" wissen, auf welches "a" es zugreifen möchte? – MarcG

3

Verwenden Typoskript der Klasse Ausdrücke hierfür:

var OpenLayers = class { 
    static Layer = class { 
     static Markers = class {} 
    } 
} 
+0

Funktioniert es auch, wenn das Top-Level-Objekt export_ed ist? Ich habe folgenden Fehler: 'Öffentliche statische Eigenschaft 'myprop' der exportierten Klasse hat oder mit dem privaten Namen '(anonyme Klasse)''. Irgendein Vorschlag? –

+0

@SayanPal weiß nicht, was Sie versuchen zu tun – Vad

Verwandte Themen