使用打字稿装饰器来强制方法中的参数
Using typescript decorators to mandate a parameter in methods
在 typescript 项目中,大约有 2000 多个事件(方法)在用户触发操作和操作完成时触发。因此,对于操作完成时触发的所有事件,我想要某种性能指标,因此参数 'executionTime' 应该是强制性的。
我计划在所有那些必须将执行时间作为参数存在的事件之上添加 method decorator。下面是我的代码
class AllEvents {
@performanceDecorator()
public static firstEvent(param1: string, param2: string, executionTime: number): void {
//some tasks...
}
@performanceDecorator()
public static secondEvent(param1: string, param2: string): void {
//some tasks...
}
@performanceDecorator()
public static thirdEvent(param1: string, param2: string, executionTime: number): void {
//some tasks...
}
}
function performanceDecorator(value: boolean) {
//..................
}
我是 typescript 的新手,无法弄清楚我应该在 函数 performanceDecorator 的主体中编写的代码,这样如果某些方法没有参数命名为 'executionTime',它会抛出错误。
扩展我之前的评论
由于您的场景中参数的数量无法固定,因此没有简单的方法可以确定您的参数中的哪一个是执行时间。
因此,使用预期的参数作为它的属性创建一个选项 class。像这样
class EventOptions {
public params: string[];
public executionTime?: number;
}
class AllEvents {
@performanceDecorator
public static firstEvent(eventOptions: EventOptions): void {
//some tasks...
console.log(eventOptions.params, eventOptions.executionTime);
}
@performanceDecorator
public static secondEvent(eventOptions: EventOptions): void {
//some tasks...
}
@performanceDecorator
public static thirdEvent(eventOptions: EventOptions): void {
//some tasks...
}
}
在这里,我已将 executionTime
作为可选参数以适合您的用例。但是您可以继续将其设为必填字段,然后您将不需要装饰器来检查该字段的有效性。 Typescript 会为您完成。
然后转到装饰器:
函数装饰器有三个参数,
target
即调用 class,在本例中为 AllEvents
propertyKey
这是作为字符串的方法名称
descriptor
这是一个 属性 描述符。它具有与您的功能相关的所有元数据
我们可以将您的装饰器写成:
function performanceDecorator(
target: Object,
propertyKey: string,
descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = (...args) => {
if (!args[0].executionTime) {
throw Error("Execution Time is missing!");
}
return originalMethod.apply(this, args);
}
return descriptor;
}
这里,我们先把原来的方法实现拿出来。然后使用条件检查 executionTime 参数的可用性。如果不存在,我们会抛出一个错误。如果存在,我们将调用原始方法实现。
在 typescript 项目中,大约有 2000 多个事件(方法)在用户触发操作和操作完成时触发。因此,对于操作完成时触发的所有事件,我想要某种性能指标,因此参数 'executionTime' 应该是强制性的。 我计划在所有那些必须将执行时间作为参数存在的事件之上添加 method decorator。下面是我的代码
class AllEvents {
@performanceDecorator()
public static firstEvent(param1: string, param2: string, executionTime: number): void {
//some tasks...
}
@performanceDecorator()
public static secondEvent(param1: string, param2: string): void {
//some tasks...
}
@performanceDecorator()
public static thirdEvent(param1: string, param2: string, executionTime: number): void {
//some tasks...
}
}
function performanceDecorator(value: boolean) {
//..................
}
我是 typescript 的新手,无法弄清楚我应该在 函数 performanceDecorator 的主体中编写的代码,这样如果某些方法没有参数命名为 'executionTime',它会抛出错误。
扩展我之前的评论
由于您的场景中参数的数量无法固定,因此没有简单的方法可以确定您的参数中的哪一个是执行时间。
因此,使用预期的参数作为它的属性创建一个选项 class。像这样
class EventOptions {
public params: string[];
public executionTime?: number;
}
class AllEvents {
@performanceDecorator
public static firstEvent(eventOptions: EventOptions): void {
//some tasks...
console.log(eventOptions.params, eventOptions.executionTime);
}
@performanceDecorator
public static secondEvent(eventOptions: EventOptions): void {
//some tasks...
}
@performanceDecorator
public static thirdEvent(eventOptions: EventOptions): void {
//some tasks...
}
}
在这里,我已将 executionTime
作为可选参数以适合您的用例。但是您可以继续将其设为必填字段,然后您将不需要装饰器来检查该字段的有效性。 Typescript 会为您完成。
然后转到装饰器:
函数装饰器有三个参数,
target
即调用 class,在本例中为AllEvents
propertyKey
这是作为字符串的方法名称descriptor
这是一个 属性 描述符。它具有与您的功能相关的所有元数据
我们可以将您的装饰器写成:
function performanceDecorator(
target: Object,
propertyKey: string,
descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = (...args) => {
if (!args[0].executionTime) {
throw Error("Execution Time is missing!");
}
return originalMethod.apply(this, args);
}
return descriptor;
}
这里,我们先把原来的方法实现拿出来。然后使用条件检查 executionTime 参数的可用性。如果不存在,我们会抛出一个错误。如果存在,我们将调用原始方法实现。