我可以使用reflect-metadata创建自定义装饰器,它工作得很好。
问题是,我不知道如何获得所有的实例装饰器。
import 'reflect-metadata';
console.clear();
function readTypes() {
const decorator: MethodDecorator = (target, propertyKey, description) => {
const args = Reflect.getMetadata(
'design:paramtypes',
target,
propertyKey
).map(c => c.name);
const ret = Reflect.getMetadata('design:returntype', target, propertyKey);
console.log(`Arguments type: ${args.join(', ')}.`);
console.log(`Return type: ${ret.name}.`);
};
return decorator;
}
class Foo {}
class Bar {
@readTypes()
public fn(a: number, b: string, c: Foo): boolean {
return true;
}
}
const barInstance = new Bar();我想从barInstance获得装饰器@readTypes的所有功能。我该怎么做呢?
请参阅工作示例:https://stackblitz.com/edit/decorators-metadata-example-nakg4c
发布于 2021-07-23 06:41:17
首先,你不是在写任何元数据,只是在读它。如果您想要查找哪些属性被修饰,那么您必须将元数据写入这些属性。
为了简单起见,让我们将装饰器简化为:
// It's a best practice to use symbol as metadata keys.
const isReadTypesProp = Symbol('isReadTypesProp')
function readTypes() {
const decorator: MethodDecorator = (target, propertyKey, description) => {
Reflect.defineMetadata(isReadTypesProp, true, target, propertyKey);
};
return decorator;
}现在,当使用装饰器时,它是在解析类时执行的,而不是在创建实例时执行。这意味着装饰器函数中的target实际上是类构造函数的prototype。
换句话说,target与Bar.prototype、barInstance.constructor.prototype或barInstance.__proto__是同一个对象。
我们知道我们可以遍历prototype对象中的所有属性名称,并查找我们之前设置的元数据:
function getReadTypesPropsFromInstance(object: {
constructor: {
prototype: unknown;
};
}) {
const target = object.constructor.prototype;
const keys = Object.getOwnPropertyNames(target);
return keys.filter(key => Reflect.getMetadata(isReadTypesProp, target, key));
}它现在返回装饰属性的名称:
const barInstance = new Bar();
console.log(getReadTypesPropsFromInstance(barInstance)); // ["fn"]https://stackoverflow.com/questions/68491610
复制相似问题