2016-09-05 4 views
0

필드 데코레이터에서 반사 사용에 문제가 있습니다. 아래 서명으로 데코레이터를 만들었습니다.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 
} 

그리고 필드에 @Inject를 사용합니다. 필드 유형이 클래스 일 때 작동하지만 필드 유형이 인터페이스 인 경우 인터페이스의 이름이 아닌 Function을 반환합니다. 어떻게 해결할 수 있습니까?

+0

인터페이스가 런타임에 존재하지 않습니다. 두 클래스와 인터페이스 모두에서 데코레이터를 사용하는 코드 부분을 추가 할 수 있습니까? –

+0

@NitzanTomer 나는 그것을 추가했습니다 – Pooya

답변

1

내가 주석에 쓴 것처럼 인터페이스는 컴파일 된 js의 일부가 아니며 출력에서 ​​컴파일러가 사용하는 것입니다.
데코레이터가 런타임에 실행되는 경우 데코 레이팅 할 인터페이스에 대한 정보가 없습니다.

class MyClass { 
    @MyDeco 
    myMember: MyType; 
} 

일을 동일합니다 : 다음 Decorators docs (Metadata section)의 마지막 예에서

그들은이 일이 보여

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

어느 때문에 당신은 다음 @Reflect.metadata 부분 자신을 포함하지 않는 경우 컴파일러가이를 추가합니다.

그러나 MyType가 인터페이스 인 경우 다음 컴파일러는 Object으로 대체되므로,이 :

interface MyInterfaceType {} 

class MyClassType {} 

class MyClass { 
    @MyDeco 
    member1: MyClassType; 

    @MyDeco 
    member2: MyInterfaceType; 
} 

는 컴파일되어 :

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

당신이 인터페이스를 사용하여 유지하고 갖고 싶어 자신의 이름을 사용한다면 데코레이터에 선택적 매개 변수를 지정하여 이름을 받도록 제안한 다음 인터페이스에서이 데코레이터를 사용하여 이름을 지정하면됩니다.
나는 그 점을 다소 그리워한다는 것을 알고 있지만, 실제로는 더 많은 선택권이 없다.

+0

'Function' 객체로 컴파일되지 않습니다. 저는 데코레이터에 인터페이스 이름을 전달할 수있는 방법이 없다고 생각합니다. 바로 당신이 맞습니다. – Pooya

+0

인터페이스가 함수라면 반환 할 것입니다. '함수' –