0

I've a problem with using reflect in field decorators. I've created a decorator with below signature:

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

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

And I use @Inject on fields. It works when field type is class but when field type is interface, it returns Function not the name of interface. How can I fix it?

Pooya
  • 4,385
  • 6
  • 45
  • 73

1 Answers1

1

As I wrote in the comment, interfaces are not part of the compiled js, they are just used by the compiler who then emits them from the output.
As decorators are being executed at runtime then there's no information about the interface which you are decorating.

In the last example in the Decorators docs (Metadata section) they show that doing this:

class MyClass {
    @MyDeco
    myMember: MyType;
}

Is equivalent of doing:

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

Which is because if you don't include the @Reflect.metadata part yourself then the compiler will add that for you.

But when MyType is an interface then the compiler will substitute it with Object, so this:

interface MyInterfaceType {}

class MyClassType {}

class MyClass {
    @MyDeco
    member1: MyClassType;

    @MyDeco
    member2: MyInterfaceType;
}

Is compiled to:

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;
}());

If you want to keep using interfaces and have their name, then I suggest that you'll have an optional parameter to your decorator which will receive the name, then when using this decorator on interfaces just place the name there.
I know that it kinda misses the point, but you don't really have more options (as I see it).

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299