// 验证参数是否为数字的装饰器
function validateNumberParameter(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
if (!args.every(arg => typeof arg === 'number')) {
throw new Error('All parameters must be numbers');
}
return originalMethod.apply(this, args);
};
return descriptor;
}
// 将返回值翻倍的装饰器
function doubleReturnValue(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const result = originalMethod.apply(this, args);
return typeof result === 'number'? result * 2 : result;
};
return descriptor;
}
class MathOperations {
@validateNumberParameter
@doubleReturnValue
multiply(a: number, b: number) {
return a * b;
}
}
// 测试
const mathOps = new MathOperations();
try {
console.log(mathOps.multiply(2, 3)); // 输出12
console.log(mathOps.multiply(2, '3')); // 抛出错误
} catch (error) {
console.error(error.message);
}
// 解释:
// 先使用`validateNumberParameter`装饰器,确保传入的参数都是数字类型。
// 再使用`doubleReturnValue`装饰器,对返回值进行翻倍操作。
// 这样设计的原因是,如果先进行返回值翻倍,而不验证参数类型,
// 可能在参数不是数字时,`multiply`方法内部逻辑出错,导致后续翻倍操作也出错。
// 先验证参数可以保证在函数执行前就发现参数类型问题,使程序更加健壮。