检查属性是否使用特定注解装饰 - Typescript

7

我该如何确定特定属性是否使用了特定注释?

例如这个类:

class A {
    @DecoratedWithThis
    thisProp: number;
}

我怎样才能知道thisPropDecoratedWithThis修饰了呢?

我的使用场景:我使用另一个文件中的类来生成属性的代码和HTML。

你能想象出其他解决方案吗?


请展示 @DecoratedWithThis。我认为您可以通过类A进行检查。像这样:if (A.thisProp.__customMetaData) {} - OPV
@DecoratedWithThis is just some function working as the decorator. function DecoratedWithThis(target: any, key: string) { //doing some stuff like getter setter } - Philipp Fock
很遗憾,这样做行不通。没有可用的_customMetaData属性。 - Philipp Fock
2个回答

12

我不知道typescript中是否有原生方法,但是可以使用'reflect-metadata'库https://github.com/rbuckton/reflect-metadata来实现,该库是对本地反射API的扩展。

装饰器只是在定义类时执行的函数。在这种情况下,您需要创建一个属性装饰器。

function (target, propertyKey) {}

如果target是您的Object.prototype,name是属性名称。

根据Reflect Metadata文档

// define metadata on an object or property
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);

// get metadata value of a metadata key on the prototype chain of an object or property
let result = Reflect.getMetadata(metadataKey, target, propertyKey);

您可以通过向属性添加元数据来解决问题,稍后可以读取该元数据以检查该属性是否已被装饰。 示例实现
import 'reflect-metadata';

const metadataKey = 'MyDecorator';

function MyDecorator(target, propertyKey) {
    Reflect.defineMetadata(metadataKey, true, target, propertyKey);
}

function myDecoratorUsingClass<T>(type:  Type<T>, propertyKey: string) {
    return myDecoratorUsingInstance(new type(), propertyKey);
}

function myDecoratorUsingInstance<T>(instance: T, propertyKey: string) {
  return !!Reflect.getMetadata(metadataKey, instance, propertyKey);
}

class MyClass {
   @MyDecorator
   property1;
   property2;
}

console.log(myDecoratorUsingClass(MyClass, 'property1')); // true
console.log(myDecoratorUsingClass(MyClass, 'property2')); // false

const instance = new MyClass();
console.log(myDecoratorUsingInstance(instance, 'property1')); // true
console.log(myDecoratorUsingInstance(instance, 'property2')); // false

注意:要使用myDecoratorUsingClass,你的类应该有一个构造函数,其中所有参数都是可选的(或没有参数)。


目前看来,这似乎是最好的方法。 - Philipp Fock

1

由于我作为新用户无法发表评论,因此我将其作为新答案发布,尽管它只是对@h0ss答案的升级。

您可以使用Reflect.hasMetadata(metadataKey,target,propertyKey)Reflect.hasOwnMetadata(metadataKey,target,propertyKey)代替!!Reflect.getMetadata(metadataKey,instance,propertyKey),如https://www.npmjs.com/package/reflect-metadata#api所述。


非常感谢。我认为他们最近扩展了reflect-metadata API,因此现在可以更轻松地处理它。 - Philipp Fock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接