首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在typescript中读取实例装饰器?

如何在typescript中读取实例装饰器?
EN

Stack Overflow用户
提问于 2021-07-23 05:20:13
回答 1查看 74关注 0票数 2

我可以使用reflect-metadata创建自定义装饰器,它工作得很好。

问题是,我不知道如何获得所有的实例装饰器。

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

发布于 2021-07-23 06:41:17

首先,你不是在写任何元数据,只是在读它。如果您想要查找哪些属性被修饰,那么您必须将元数据写入这些属性。

为了简单起见,让我们将装饰器简化为:

代码语言:javascript
复制
// 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

换句话说,targetBar.prototypebarInstance.constructor.prototypebarInstance.__proto__是同一个对象。

我们知道我们可以遍历prototype对象中的所有属性名称,并查找我们之前设置的元数据:

代码语言:javascript
复制
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));
}

它现在返回装饰属性的名称:

代码语言:javascript
复制
const barInstance = new Bar();
console.log(getReadTypesPropsFromInstance(barInstance)); // ["fn"]

Working example

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68491610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档