类的装饰器
装饰器(Decorators)是一种用于修改类的行为的特殊类型声明,它可以被附加到类声明、方法、访问符、属性或参数上。装饰器可以用来扩展、修改或注释类及其成员。在 TypeScript 中,装饰器通过 @ 符号以及后面紧跟着的装饰器工厂函数来使用。
类装饰器
类装饰器是应用于类声明之前的装饰器,用来修改类的行为或元数据。
function Greeter(target: Function) {
target.prototype.greet = function () {
console.log('Hello' + this.name);
}
}
// 修饰类
@Greeter
class Person {
name: string
constructor(value: string) {
this.name = value
}
}
let p = new Person('sir');
p.greet()
Greeter 是一个类装饰器,它接受一个函数作为参数,并扩展了类 Person 的原型,添加了一个 greet 方法。
方法装饰器
方法装饰器是应用于类方法之前的装饰器,用来修改方法的行为或元数据。
target 对应类的构造函数
function Decorator(target: any, key: string) {
console.log(target,key)
}
class Test {
name: string
constructor(name: string) {
this.name = name
}
// 静态方法
@Decorator
static getName() {
return '123'
}
}
// 日志方法
function Log(target:any, key:string, descriptor: PropertyDescriptor) {
let originalFn = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling Method ${key} with args: ${args}`)
return originalFn.apply(this, args)
}
}
class Calc {
@Log
add(a:number, b:number): number {
return a + b;
}
}
let calc = new Calc();
calc.add(2,3); // Calling Method add with args: 2,3 5
在上述示例中,Log 是一个方法装饰器,它接受三个参数,分别是目标类的原型(target)、属性名称(key)和属性描述符(descriptor)。在装饰器内部,我们可以修改方法的行为,这里我们在方法调用前后打印了日志。
属性装饰器
属性装饰器是应用于类属性之前的装饰器,用来修改属性的行为或元数据。
function ReadOnly(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get: () => value,
set: (v) => {
throw new Error(`Property ${key} is read-only`);
},
enumerable: true,
configurable: true
});
}
class Person {
@ReadOnly
name: string;
constructor(name: string) {
this.name = name;
}
}
let person = new Person('Alice');
console.log(person.name); // 输出: Alice
// person.name = 'Bob'; // Error: Property name is read-only
在上述示例中,ReadOnly 是一个属性装饰器,它接受两个参数,分别是目标类的原型(target)和属性名称(key)。在装饰器内部,我们通过修改属性的描述符来实现将属性设为只读。