在本文中,我们将在打字稿中深入研究装饰者,探索他们的类型,并提供实用的例子以帮助您发挥其全部潜力。
什么是装饰师? ð -
在其核心上,装饰器只是使用@
符号应用于类,方法,属性或参数的功能。它们可用于各种目的,包括:
- 记录和调试:在执行方法之前和之后添加记录语句。
- 验证:检查输入或输出的有效性。
- 授权:控制对某些方法或路线的访问。
- 回忆:缓存昂贵操作的结果。
- 依赖注入:自动将依赖项注入类。
- 元数据集合:存储有关类或属性的其他信息。
班级装饰师ð
班级装饰师应用于课程。他们将类构造函数作为其唯一参数,可用于修改类或向其添加元数据。
function MyDecorator(target: Function) {
console.log('Class decorator called on', target);
}
@MyDecorator
class MyClass {
constructor() {
console.log('MyClass constructor');
}
}
// Output:
// Class decorator called on [Function: MyClass]
// MyClass constructor
方法装饰师ð
方法装饰器被应用于类中的方法。他们接收三个参数:目标类原型,方法名称和属性描述符。
function LogMethod(target: Object, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${key} with arguments: ${args}`);
const result = originalMethod.apply(this, args);
console.log(`${key} returned: ${result}`);
return result;
};
return descriptor;
}
class Calculator {
@LogMethod
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(2, 3);
// Output:
// Calling add with arguments: 2,3
// add returned: 5
物业装饰师ð
属性装饰器用于修改类中的属性。他们收到两个参数:目标类原型和属性名称。
function Validate(target: any, key: string) {
let value = target[key];
const getter = () => value;
const setter = (newValue: any) => {
if (typeof newValue !== 'number' || newValue < 0) {
throw new Error('Invalid value');
}
value = newValue;
};
Object.defineProperty(target, key, {
get: getter,
set: setter,
});
}
class Product {
@Validate
price: number;
constructor(price: number) {
this.price = price;
}
}
const product = new Product(50);
product.price = -10; // Throws an error
// Output:
// Error: Invalid value
参数装饰器ð
参数装饰器应用于类中方法的参数。他们接收三个参数:目标类原型,方法名称和参数的索引。
const Injectable = (): ParameterDecorator => {
return (target: any, key: string | symbol, index: number) => {
// Register the dependency injection here
console.log(`Injecting parameter at index ${index} in method ${key}`);
};
};
class UserService {
constructor(private readonly logger: Logger) {}
@Injectable()
log(message: string) {
this.logger.log(message);
}
}
const logger = new Logger();
const userService = new UserService(logger);
userService.log('Hello, Decorators!');
// Output:
// Injecting parameter at index 0 in method log
// Hello, Decorators!