代码示例
// 自定义错误类型
class InvalidParameterTypeError extends Error {
constructor(message: string) {
super(message);
this.name = 'InvalidParameterTypeError';
}
}
// 参数装饰器
function validateNumber(target: any, propertyKey: string, parameterIndex: number) {
return function (target: any, ...args: any[]) {
if (typeof args[parameterIndex]!== 'number') {
throw new InvalidParameterTypeError(`参数 ${parameterIndex} 必须是数字类型`);
}
return Reflect.apply(target, this, args);
};
}
class ExampleClass {
@validateNumber
exampleMethod(num: number) {
return num * 2;
}
}
// 测试
try {
const example = new ExampleClass();
console.log(example.exampleMethod(5)); // 输出 10
console.log(example.exampleMethod('5')); // 抛出错误
} catch (error) {
if (error instanceof InvalidParameterTypeError) {
console.error(error.message);
}
}
装饰器相较于普通类型检查的优势
- 代码复用:装饰器可以在多个方法的参数上复用,而普通类型检查需要在每个需要检查的地方重复编写检查代码。例如,如果有多个方法都需要对某个参数进行数字类型检查,使用装饰器只需要编写一次检查逻辑,然后应用到不同方法的参数上即可。
- 分离关注点:装饰器将类型检查逻辑从业务逻辑中分离出来。普通类型检查可能会使业务方法的代码变得冗长,混入了类型检查的逻辑,而装饰器让业务方法专注于自身的功能实现,类型检查逻辑在装饰器中实现,提高了代码的可读性和维护性。
- 可维护性:当类型检查规则发生变化时,只需要修改装饰器中的逻辑,所有应用该装饰器的地方都会受到影响,而不需要逐个修改每个业务方法中的类型检查代码。