您不能将装饰器添加到直接函数中。来自 Typescript 文档 (https://www.typescriptlang.org/docs/handbook/decorators.html):
装饰器
装饰器是一种可以附加到类的特殊声明
声明、方法、访问器、属性或参数。装饰者使用表格
@expression,其中表达式必须计算为将在以下位置调用的函数
带有装饰声明信息的运行时。
当您尝试时,您会发现它不起作用,因为脚本编写的装饰器函数假定有一个类链接到正在装饰的内容,如文档中所述。
但是,我不推荐这样做,你可以在一个类中拥有你需要的功能,那么以下将适用:
方法装饰器
方法装饰器在方法之前声明
宣言。装饰器应用于属性描述符
方法,可用于观察、修改或替换方法
定义。不能在声明文件中使用方法装饰器,
在重载或任何其他环境上下文中(例如在声明中
类)。
方法装饰器的表达式将作为函数调用
在运行时,使用以下三个参数:
- 静态成员的类的构造函数,或者
- 实例成员的类的原型。成员的名称。
- 成员的属性描述符。
然后你可以像typescript Playground example那样做一些丑陋的黑客攻击
为方便起见,我也在此处提供代码。如果您检查 typescript Playground 或编译此代码,那么要做的一件好事是查看生成的 Javascript,它清楚地表明这不是为直接函数编写的。
function noisy() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
alert(`I am decorating ${ propertyKey }`);
};
}
class Test {
@noisy()
public testMethod() {
}
}
class DynamicTest {
}
const testInstance = new Test();
testInstance.testMethod();
let dynamics = ["do", "something"];
for (let dynFunction of dynamics) {
DynamicTest.prototype[dynFunction] = new Function(`alert("I am Dynamic ${dynFunction}")`);
let decorator = noisy();
decorator(DynamicTest.prototype, dynFunction, null);
}
const dynamicTestInstance = new DynamicTest();
dynamicTestInstance["do"]();
dynamicTestInstance["something"]();
function noisy() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
alert(`I am decorating ${ propertyKey }`);
};
}
class Test {
@noisy()
public testMethod() {
}
}
class DynamicTest {
}
const testInstance = new Test();
testInstance.testMethod();
let dynamics = ["do", "something"];
for (let dynFunction of dynamics) {
DynamicTest.prototype[dynFunction] = new Function(`alert("I am Dynamic ${dynFunction}")`);
let decorator = noisy();
decorator(DynamicTest.prototype, dynFunction, null);
}
const dynamicTestInstance = new DynamicTest();
dynamicTestInstance["do"]();
dynamicTestInstance["something"]();
在不了解您的具体问题的情况下,我无法想到需要以这种方式生成函数。也许是一个外部逻辑数据流,比如规则引擎?无论如何,这种动态生成很难测试和维护,因此请记住这一点,并在可能的情况下考虑其他方法。