微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在打字稿中读取实例装饰器?

如何解决如何在打字稿中读取实例装饰器?

我可以使用 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',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();

我想从 @readTypes 获取所有带有装饰器 barInstance函数。我该怎么做?

参见工作示例: https://stackblitz.com/edit/decorators-metadata-example-nakg4c

解决方法

首先,您没有编写任何元数据,只是读取它。如果要查找哪些属性被修饰,则必须将元数据写入这些属性。

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

// 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.prototypebarInstance.constructor.prototypebarInstance.__proto__

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

function getReadTypesPropsFromInstance(object: {
  constructor: {
    prototype: unknown;
  };
}) {
  const target = object.constructor.prototype;
  const keys = Object.getOwnPropertyNames(target);
  return keys.filter(key => Reflect.getMetadata(isReadTypesProp,key));
}

现在返回修饰属性的名称:

const barInstance = new Bar();
console.log(getReadTypesPropsFromInstance(barInstance)); // ["fn"]

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。