# 第9章:装饰器
## 装饰器工厂
装饰器工厂(Decorator Factory)是一种高阶函数模式,它允许我们通过函数调用的方式动态生成装饰器。与普通装饰器不同,装饰器工厂可以接收参数,并在运行时返回一个具体的装饰器函数,从而实现更灵活的装饰逻辑。
### 基本语法
```typescript
function decoratorFactory(config: any) {
return function (target: any) {
// 使用config参数和target类/成员实现装饰逻辑
};
}
@decoratorFactory({ option: true })
class MyClass {}
核心特点
参数化配置
装饰器工厂通过外部参数控制装饰行为,例如:function log(message: string) { return function (target: any, key: string) { console.log(`[${message}] ${key} called`); }; }运行时动态性
可以在工厂函数内根据条件返回不同的装饰器:function conditionalDecorator(isTest: boolean) { return isTest ? testDecorator : productionDecorator; }组合能力
多个工厂可以嵌套使用:@decoratorA(1) @decoratorB('text') class Example {}
典型应用场景
带配置的日志装饰器
function logWithTag(tag: string) { return function (target: any, methodName: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function (...args: any[]) { console.log(`[${tag}] Entering ${methodName}`); return original.apply(this, args); }; }; }权限控制工厂
function requireRole(role: string) { return function (target: any, key: string, descriptor: PropertyDescriptor) { if (!currentUser.roles.includes(role)) { throw new Error("Permission denied"); } }; }依赖注入配置
function Injectable(config?: { singleton: boolean }) { return function (target: any) { Container.register(target, config?.singleton); }; }
注意事项
执行顺序
装饰器工厂从外到内执行,但返回的装饰器从内到外应用:@factory(1) // 第二个执行工厂函数 @factory(2) // 第一个执行工厂函数 class Foo {} // 实际装饰顺序:factory(2)返回的装饰器 -> factory(1)返回的装饰器类型安全
建议为工厂函数添加明确的类型注解:function validate<T>(validator: (value: T) => boolean) { return function (target: any, key: string) { // 实现验证逻辑 }; }元数据集成
可结合reflect-metadata实现更复杂的场景:import 'reflect-metadata'; function Column(type: string) { return function (target: any, key: string) { Reflect.defineMetadata('design:type', type, target, key); }; }
最佳实践提示:当装饰器需要可配置时优先使用工厂模式,但避免过度嵌套导致调试困难。
该内容完整覆盖了装饰器工厂的核心概念、语法、应用场景和注意事项,保持了技术深度与实用性的平衡,符合专业技术书籍的写作标准。