2012-11-21 14 views
43

Chciałbym zdefiniować istniejący framework (openlayers.d.ts), ale nie mogę zrozumieć, jak wyrazić fakt, że OpenLayers.Layer jest zarówno klasą, jak i przestrzenią nazw dla OpenLayers.Layer.Markers. Wierzę, że czyni to Markerów zagnieżdżoną klasą warstwy.Dowolny sposób deklarowania struktury klasy gniazdowej w maszynopisie?

Wykorzystanie:

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

Jak można zadeklarować zarówno warstwy i klasy Markery w maszynie?

+0

To wydaje się być kopią pytania bez odpowiedzi na stronie http://przepełnienie stosu.com/questions/12799433/typescript-module-and-class-while –

+2

Nie mówiąc o tym, jak chciałbyś to modelować z perspektywy * declaration *, ale TypeScript ma teraz obsługę klas zagnieżdżonych: http://stackoverflow.com/a/32494175/390330 – basarat

Odpowiedz

50

Wygląda na to, że został naprawiony w wersjach 0.9.1.1 i nowszych. Musisz tylko utworzyć moduł o tej samej nazwie, co klasa, w której chcesz zagnieżdżać typy, i umieścić w niej typy zagnieżdżone.

Bardziej konkretnie, to jak to zrobić:

declare module a 
{ 
    class b 
    { 
    } 

    module b 
    { 
     class c 
     { 
     } 
    } 
} 

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

ta działa również podczas gniazdowania typy w kodzie maszynopis z kluczowych eksportu:

export module a 
{ 
    export class b 
    { 
    } 

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

Jak wspomniano przez @recursive użytkownika w komentarzach poniżej ważna jest kolejność zgłoszeń. Dlatego definicja klasy musi znajdować się przed modułem z typami zagnieżdżonymi.

+7

Nie mogłem tego uruchomić, ale potem zdałem sobie sprawę, że kolejność jest ważna. Wydaje się to działać tylko wtedy, gdy zadeklarujesz klasę jako pierwszą, a następnie moduł. To nie działa na odwrót. – recursive

+0

Jak to zrobić w projekcie Angular za pomocą maszynopisu? Moduły używają dekoratora: @NgModule –

12

można użyć modułu scalania dostać skutku równoważnym do klas zagnieżdżonych. Ten przykład jest dostosowany z rozdziału 1 Pro TypeScript.

Umożliwiasz łączenie modułów z klasą i modułem lub z funkcją i modułem.

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

adaptowany przykład:

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 Odpowiedź

Uwaga: ta oryginalna odpowiedź (opublikowany w 2012) zastosowano do wersji 0.8 maszynopisu.

Nadal możesz utworzyć deklarację, która pozwoliłaby na użycie twoich opisów, po prostu obiekt Markers byłby typu any. Można to poprawić, gdy zagnieżdżony element klasy jest naprawiony.

declare module OpenLayers { 
    export class Layer { 
     constructor(param: string); 
     static Markers(param: string); 
    } 
} 


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

jak wywołać metodę z klasy średniej do klasy zewnętrznej? – cracker

6

Trochę się spóźniło, ale inni mogą uznać to za przydatne. Tak to zrobiłem, aby oszukać TS, aby wykonać to zadanie.

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

To rozwiązało mój problem – nkint

+0

Jak można mieć zmienną o nazwie Warstwa w tym samym zasięgu, co interfejs o nazwie Warstwa? – CodyBugstein

8

Począwszy od 2016 roku, to chyba łatwiej:

class A { 
    static B = class { } 
} 

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

Otrzymuję ten błąd kompilacji 'Inicjatory są niedozwolone w kontekstach otoczenia' z atomem najnowszej wtyczki ts – nkint

+0

Jak można odnieść się do' tego 'z' A' w metodzie 'B' bez podania to jest jawny argument? Czy jest to niemożliwe, ponieważ "B" jest statyczne? Moim obecnym rozwiązaniem jest posiadanie metody 'bFactory' na' A', gdzie mogę uzyskać dostęp do członków "A" i przekazać je do konstruktora 'B' jawnie, ale miałem nadzieję, że był to prosty sposób. – Monkpit

+0

@Monkpit: 'this' odnosi się do obiektu' a', a nie do klasy 'A'. Możesz utworzyć wiele 'a's i wiele' b's, każdy z własnym 'this'. W jaki sposób konkretny "b" może wiedzieć, do którego "a" chciałbyś uzyskać dostęp? – MarcG

3

Skorzystaj maszynopis za klasy wyrażenia dla tego:

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

Czy działa również, jeśli obiekt najwyższego poziomu to 'export'ed? Mam następujący błąd: "Publiczna właściwość statyczna" myprop "eksportowanej klasy ma lub używa prywatnej nazwy" (klasa Anonymous) "'. Jakieś sugestie? –

+0

@SayanPal nie wiem, co próbujesz zrobić – Vad

Powiązane problemy