TypeScript 装饰器
·
TypeScript 装饰器
TypeScript 装饰器是一种特殊语法,允许你在不修改类、方法、属性或参数本身代码的情况下,动态添加元数据或修改其行为。它基于装饰器模式,常用于实现日志记录、验证、依赖注入等功能。装饰器在 TypeScript 中通过 @decoratorName 的语法应用,并需要在 tsconfig.json 中启用 experimentalDecorators 选项。
基本概念
- 装饰器类型:
- 类装饰器:应用于类构造函数。
- 方法装饰器:应用于类方法。
- 属性装饰器:应用于类属性。
- 参数装饰器:应用于方法参数。
- 访问器装饰器:应用于 getter/setter。
- 工作原理:装饰器本质上是一个高阶函数,接收目标对象、属性名等参数,并返回修改后的描述符或新值。例如,方法装饰器的签名是:
其中:function decorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) { // 修改行为 }target:目标类的原型或构造函数。propertyKey:方法或属性的名称(字符串)。descriptor:属性描述符(如可写性、配置性)。
常见用途
装饰器在以下场景中非常实用:
- 日志记录:自动记录方法调用和参数。
- 验证:检查输入参数或属性值是否有效。
- 性能监控:测量方法执行时间。
- 依赖注入:在框架(如 Angular)中自动注入服务。
- 缓存:存储方法结果以避免重复计算。
代码示例
以下是一个简单的日志装饰器实现,它会在方法调用时输出日志信息。首先,定义一个方法装饰器:
// 定义日志装饰器:记录方法调用和结果
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value; // 保存原始方法
descriptor.value = function(...args: any[]) {
console.log(`调用方法: ${propertyKey}, 参数: ${JSON.stringify(args)}`);
const result = originalMethod.apply(this, args); // 执行原始方法
console.log(`方法结果: ${result}`);
return result;
};
return descriptor; // 返回修改后的描述符
}
// 应用装饰器到类方法
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
// 测试代码
const calc = new Calculator();
calc.add(2, 3); // 控制台输出: 调用方法: add, 参数: [2,3] 和 方法结果: 5
方法装饰器
function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor): void {
console.log('target', target, `Method ${propertyKey} was called.`, 'descriptor', descriptor);
}
class MyClass1 {
@LogMethod
myMethod() {
console.log('MyMethod was called.');
}
}
// const myInstance1 = new MyClass1();
// myInstance1.myMethod(); // 输出: Method myMethod was called.
属性装饰器
/**
* 默认值装饰器工厂函数
* @param value - 要设置的默认值
* @returns 返回一个装饰器函数
*/
function DefaultValue(value: any) {
// 返回装饰器函数
// 该装饰器用于为类的属性设置默认值
return function (target: any, propertyKey: string) {
console.log('target', target, 'propertyKey', propertyKey);
// 将指定的默认值赋给目标类的属性
target[propertyKey] = value;
};
}
class MyClass2 {
@DefaultValue('default value')
myProperty: string;
}
// const myInstance2 = new MyClass2();
// console.log(myInstance2.myProperty); // 输出: default value
参数装饰器
/**
*参数装饰器
*/
function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
console.log('target', target, 'propertyKey', propertyKey, 'parameterIndex', parameterIndex);
}
class MyClass3 {
myMethod(@LogParameter param: string) {
console.log('param', param);
}
}
const myInstance3 = new MyClass3();
myInstance3.myMethod('hello'); // 输出: param hello
注意事项
- 启用装饰器:在
tsconfig.json中添加"experimentalDecorators": true。 - 执行顺序:装饰器在类定义时立即执行(而非运行时),多个装饰器时从下到上应用。
- 浏览器支持:装饰器是 ECMAScript 提案,尚未成为标准,TypeScript 中为实验性功能。建议在编译时使用 Babel 或 TypeScript 编译器处理。
更多推荐


所有评论(0)