2017-02-16 6 views
5

typescript에서 속성 데코레이터를 사용하여 클래스의 메타 데이터를 설정할 수 있습니까? 아래의 코드를 고려하십시오. 클래스 데코레이터의 "target"은 속성 데코레이터의 "target"과 분명히 같지 않습니다. 다른 하나에서 파생 될 수 있습니까?는 속성 장식자가 해당 클래스의 메타 데이터를 typescript 할 수 있습니까?

import 'reflect-metadata'; 


const MY_CLASS_DECORATOR_KEY = 'MyClassDecoratorKey'; 
const MY_PROPERTY_DECORATOR_KEY = 'MyPropertyDecoratorKey'; 

export const MyClassDecorator = options => { 
    return function (target) { 
     console.log('class target: ' , target); 
     Reflect.defineMetadata(MY_CLASS_DECORATOR_KEY, options, target); 
    }; 
}; 

export const MyPropertyDecorator = (options): PropertyDecorator => { 
    return (target, property) => { 
     console.log('property target: ' , target); 
     const metadata = Reflect.getMetadata(MY_PROPERTY_DECORATOR_KEY, target) || {}; 
     metadata[property] = options; 
     Reflect.defineMetadata(MY_PROPERTY_DECORATOR_KEY, metadata, target); 
    }; 
}; 

@MyClassDecorator('my class decorator value') 
class MyClass { 
    @MyPropertyDecorator('first my property decorator value') 
    myFirstProperty: any; 

    @MyPropertyDecorator('second my property decorator value') 
    mySecondProperty: any; 
} 

console.log('keys: ', Reflect.getMetadataKeys(MyClass)); 

주 출력 :

property target: MyClass {} 
property target: MyClass {} 
class target: function MyClass() { 
    } 
keys: [ 'MyClassDecoratorKey' ] 

가 어떻게 또한 속성 장식의 키를 표시하기 위해 메타 데이터 키를받을 수 있나요?

답변

3

네, 당신은 당신이 당신의 데코레이터에서 원하는 것을 자유롭게 할 수 있습니다. 그러나 당신이 알았 듯이, 당신의 문제는 당신이 지나가고있는 대상과 관련이 있습니다.

기본적 특성 장식에서 target 파라미터는 장식 정적 속성 또는 인스턴스 속성 사용 여부에 따라 두 가지 중 하나가 될 수

정적 속성에서 target 속성 것 클래스 생성자 함수. 이는 정적 속성에서 대상이 클래스 데코레이터와 완전히 동일하다는 것을 의미합니다.

그러나 인스턴스 속성에서 target 매개 변수는 생성자가 아닌 만든 클래스의 prototype이됩니다. 이것이 당신이 보는 행동을 보는 이유입니다. 인스턴스 속성의 경우 메타 데이터는 클래스 장식 자의 경우와 마찬가지로 constructor에 연결되지 않습니다.

constructor이라는 속성에 저장되어있는 프로토 타입 인스턴스를 사용하면 쉽게 생성자 함수를 얻을 수 있기 때문에 여전히 희망이 있습니다.

export const MyPropertyDecorator = (options): PropertyDecorator => { 
    return (target, property) => { 
     var classConstructor = target.constructor; 
     console.log('property target: ' , classConstructor); 
     const metadata = Reflect.getMetadata(MY_PROPERTY_DECORATOR_KEY, classConstructor) || {}; 
     metadata[property] = options; 
     Reflect.defineMetadata(MY_PROPERTY_DECORATOR_KEY, metadata, classConstructor); 
    }; 
}; 

참고 : 귀하의 경우 그래서, 당신은 당신이 이렇게 찾고있는 동작을 얻을 수 위의 변화는 정적 속성 인스턴스 속성 작동하지만,하지 않을 것입니다. 두 유형의 속성을 모두 처리해야하는 경우 사용할지 여부를 결정하기 위해 추가 논리를 추가해야합니다. target 또는 target.constructor

+0

환상적입니다. 당신의 대답은 내가 필요한 것입니다. 정말 고마워! 그러나 다른 방향으로 가서 메타 데이터를 생성자 대신 프로토 타입에 넣으려고한다고 가정합니다. 다른 방향으로 갈 수 있습니까? – bkinsey808

+0

물론, target.prototype을 수행하십시오. – dtabuenc