第9章:装饰器
实际应用场景(如框架集成)
装饰器在 TypeScript 中虽然仍处于实验性阶段(需在 tsconfig.json 中启用 experimentalDecorators),但已被广泛用于现代前端框架和工具库中。以下是几个典型的实际应用场景:
1. Angular 中的依赖注入与组件定义
Angular 深度依赖装饰器实现核心功能:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
@Input() title: string;
@Output() onClick = new EventEmitter();
}
@Component:标记类为 Angular 组件,并配置元数据(如模板、样式)。@Input/@Output:声明组件与父组件的通信接口。
2. NestJS 的控制器与依赖注入
NestJS 使用装饰器构建后端服务:
@Controller('users')
export class UsersController {
@Get()
findAll(@Query() query: PaginationDto) {
return this.usersService.findAll(query);
}
}
@Controller:定义路由前缀。@Get:映射 HTTP 方法到具体函数。@Query:自动解析请求参数为类型安全的 DTO。
3. TypeORM 中的实体定义
数据库实体通过装饰器配置:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 100 })
name: string;
}
@Entity:标记类对应数据库表。@Column:定义字段类型和约束。
4. 自定义日志或性能监控
装饰器可复用横切关注点逻辑:
function logExecutionTime(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const start = performance.now();
const result = originalMethod.apply(this, args);
console.log(`${key} executed in ${performance.now() - start}ms`);
return result;
};
}
class ApiService {
@logExecutionTime
fetchData() { /* ... */ }
}
5. 权限控制(如路由守卫)
结合框架实现角色校验:
function AdminOnly(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (user: User) {
if (user.role !== 'admin') throw new Error('Forbidden');
return originalMethod.apply(this, [user]);
};
}
class DashboardController {
@AdminOnly
renderAdminPanel(user: User) { /* ... */ }
}
注意事项
- 实验性特性:装饰器语法可能随 TC39 提案变化而调整。
- 框架兼容性:不同框架对装饰器的实现可能有差异(如参数装饰器在 Angular 和 NestJS 中的行为)。
- 性能影响:复杂的装饰器链可能增加启动时间,需谨慎设计。
通过装饰器,开发者能以声明式的方式增强代码功能,同时保持类型安全。它是 TypeScript 在大型项目中提升可维护性的重要工具之一。
