[英]can typescript property decorators set metadata for the class?
在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' ]
如何獲取元數據鍵以顯示屬性裝飾器中的鍵?
是的,你可以自由地在你的裝飾工作中做任何你想做的事情,但是當你發現時,你的問題就在於你正在通過的目標。
基本上,在屬性裝飾器中, 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.