typescript - 我在使用方法装饰器和类装饰器时遇到问题
问题描述
我有一个类装饰器,该类装饰器更改了类并在其中添加了一个属性。然后我有一个方法装饰器,它位于具有该类装饰器的类中,并且该方法装饰器试图访问由另一个装饰器创建的类中的属性。
// 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: Cannot read property 'text' of undefined
为什么?
解决方案
就像提香所说,类装饰器在方法装饰器之后运行,这就是您的示例代码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 = ...
}
推荐阅读
- enums - AENUM动态创建类体会导致pylint警告
- sql - 在字符串中查找特定单词,返回单词开头的前 4 个字符
- google-sheets - 谷歌电子表格将值从数千转换为数百万
- c++ - (C++) 生成数组中的第一个 p*n 完美平方数(从键盘输入 p 和 n)
- javascript - 未在 HTML 上定义未捕获的 ReferenceError google(电子表格)?
- python - 如何授予 CentOS 服务器上的其他用户访问虚拟环境的权限
- angularjs - 在服务中调用承诺后无法在我的控制器中获取值
- javascript - ASP.NET Core 2.2 AntiForgeryToken with JSON.Stringify
- python - ImportError:需要“六”包
- entity-framework - ForeignKey 到非 PrimaryKey 但仍然是唯一的