簡體   English   中英

可以使用typescript屬性裝飾器為類設置元數據嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM