【问题标题】:I'm having a problem with method decorators and class decorators我在使用方法装饰器和类装饰器时遇到问题
【发布时间】:2019-04-21 16:31:18
【问题描述】:

我有一个类装饰器,该类装饰器更改了类并在其中添加了一个属性。 然后我有一个方法装饰器,它位于具有该类装饰器的类中,并且该方法装饰器试图访问由另一个装饰器创建的类中的属性。

// The Class Decorator
export function SomeDecorator(): ClassDecorator {
  return target => {
    target['property'] = { text: 'some text' };

    return target;
  }
}

// The Method Decorator
export function SomeOtherDecorator(): MethodDecorator {
  return (target, propertyKey: string, propertyDescriptor: PropertyDescriptor) => {
    console.log(target['property'].text);
  }
}

// The Class
@SomeDecorator()
export class SomeClass {
  @SomeOtherDecorator()
  someMethod() {}
}

它会在运行时回答这个问题: TypeError:无法读取未定义的属性“文本”

为什么?

【问题讨论】:

  • 类装饰器在方法装饰器之后运行
  • 那我需要怎么做呢?
  • 除了console.log之外,你还想在方法装饰器中使用target['property'].text做什么?

标签: typescript decorator


【解决方案1】:

正如 Titian 所说,类装饰器在方法装饰器之后运行,这就是您的示例代码 console.log(target['property'].text); 失败的原因。

不确定您的实际用例,但如果您可以推迟对target['property'] 的访问,则不会有任何问题。

function SomeOtherDecorator(): MethodDecorator {
  return (target, propertyKey: string, propertyDescriptor: PropertyDescriptor) => {
    const fn = descriptor.value;
    // no problem, because `target['property']` is only accessed
    // when the decorated method (not decorator) is called.
    descriptor.value = (...args) => {
      console.log(target['property'].text);
      return fn.apply(target, args);
    };
  }
}

您甚至可以使用 getter 来懒惰地运行装饰器,这应该可以处理大多数用例。

function SomeOtherDecorator(): MethodDecorator {
  return (target, propertyKey: string, propertyDescriptor: PropertyDescriptor) => {
    const fn = descriptor.value;
    let decoratedFn;
    descriptor.get = () => {
      if (decoratedFn) return decoratedFn;
      // do whatever you want to decorate the method/fn
      // including access to `target['property']`
      decoratedFn = ...
    }

【讨论】:

    猜你喜欢
    • 2020-01-11
    • 2014-01-14
    • 2012-09-11
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2020-01-02
    • 2019-02-03
    相关资源
    最近更新 更多