2016-09-05 1 views
0

Ich habe ein Problem mit Reflect in Felddekoratoren. Ich habe einen Dekorateur mit folgender Signatur erstellt:Funktion anstelle des Schnittstellennamens bei Verwendung von Reflect

export function Inject() { 
    return function (clazz, name) { 
     ....... 
     let typeName: string = Reflect.getOwnMetadata("design:type", clazz, name).name; 
     ......... 
    } 
} 

class MyClass{ 
    @Inject() 
    private $q:ng.IQService 
} 

Und ich benutze @Inject auf Felder. Es funktioniert, wenn der Feldtyp die Klasse ist, aber wenn der Feldtyp Schnittstelle ist, gibt es Function nicht den Namen der Schnittstelle zurück. Wie kann ich es reparieren?

+0

Schnittstellen existieren zur Laufzeit nicht. Können Sie den Teil des Codes hinzufügen, in dem Sie diesen Decorator für Klassen und Schnittstellen verwenden? –

+0

@NitzanTomer Ich habe es hinzugefügt – Pooya

Antwort

1

Wie ich im Kommentar geschrieben habe, sind Schnittstellen nicht Teil der kompilierten js, sie werden nur vom Compiler verwendet, der sie dann aus der Ausgabe ausgibt.
Da Dekoratoren zur Laufzeit ausgeführt werden, gibt es keine Informationen über die zu dekorierende Oberfläche.

Im letzten Beispiel in der Decorators docs (Metadata section) sie zeigen, dass dies zu tun:

class MyClass { 
    @MyDeco 
    myMember: MyType; 
} 

entspricht tun:

class MyClass { 
    @MyDeco 
    @Reflect.metadata("design:type", MyType) 
    myMember: MyType; 
} 

Welche ist denn wenn Sie beinhalten nicht die @Reflect.metadata Teil selbst dann Der Compiler wird das für Sie hinzufügen.

Aber wenn MyType ist eine Schnittstelle, dann wird der Compiler es mit Object ersetzen, so dass dies:

interface MyInterfaceType {} 

class MyClassType {} 

class MyClass { 
    @MyDeco 
    member1: MyClassType; 

    @MyDeco 
    member2: MyInterfaceType; 
} 

Ist zusammengestellt:

var MyClass = (function() { 
    function MyClass() { 
    } 
    __decorate([ 
     MyDeco, 
     __metadata('design:type', MyClassType) 
    ], MyClass.prototype, "member1", void 0); 
    __decorate([ 
     MyDeco, 
     __metadata('design:type', Object) 
    ], MyClass.prototype, "member2", void 0); 
    return MyClass; 
}()); 

Wenn Sie Schnittstellen zu halten und haben ihre Name, dann schlage ich vor, dass Sie einen optionalen Parameter zu Ihrem Dekorateur haben werden, der den Namen erhalten wird, dann wenn Sie diesen Dekorator auf Schnittstellen verwenden, setzen Sie einfach den Namen dort.
Ich weiß, dass es irgendwie den Punkt vermisst, aber Sie haben wirklich nicht mehr Optionen (wie ich es sehe).

+0

Es kompiliert zu 'Funktion' nicht Objekt, ich denke, es gibt keine Möglichkeit, Schnittstellenname an den Dekorateur übergeben und Sie haben Recht – Pooya

+0

Ich denke, wenn die Schnittstelle eine Funktion ist, dann wird es eine zurückgeben 'Funktion' –

Verwandte Themen