装饰器
装饰器简介
装饰器(Decorator)是一种特殊类型的声明,它能够被附加到类声明、方法、访问符、属性或参数上。装饰器使用 @expression
这种形式,expression
求值后必须为一个函数,它在运行时被调用,被装饰的声明信息会作为参数传入。
常用装饰器类型
类装饰器
typescript
function classDecorator(constructor: Function) {
// 可以修改类的属性和方法
}
@classDecorator
class Example {
// ...
}
方法装饰器
typescript
function methodDecorator(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
// 可以修改方法的实现
}
class Example {
@methodDecorator
method() {}
}
属性装饰器
typescript
function propertyDecorator(target: any, propertyKey: string) {
// 可以修改属性的元数据
}
class Example {
@propertyDecorator
property: string;
}
实现依赖注入
使用装饰器实现简单的依赖注入容器:
typescript
// 存储元数据的容器
const Container = new Map();
// 注入装饰器
function Injectable() {
return function (target: any) {
Container.set(target.name, target);
};
}
// 使用示例
@Injectable()
class UserService {
getUsers() {
return ['user1', 'user2'];
}
}
@Injectable()
class UserController {
constructor(private userService: UserService) {}
}
反射元数据
结合 reflect-metadata
库使用装饰器可以实现更强大的功能:
typescript
import 'reflect-metadata';
// 定义元数据装饰器
function Module(metadata: any) {
return function (target: any) {
Reflect.defineMetadata('module', metadata, target);
};
}
// 使用示例
@Module({
controllers: [UserController],
providers: [UserService],
})
class AppModule {}
最佳实践
- 装饰器应该保持简单和单一职责
- 使用装饰器工厂函数来传递参数
- 注意装饰器的执行顺序
- 合理使用反射元数据扩展功能
注意事项
- 装饰器是实验性特性,需要在
tsconfig.json
中启用experimentalDecorators
- 装饰器执行时机是在类定义时,而不是实例化时
- 多个装饰器组合时,执行顺序是从下到上