TypeScript 语言 方法装饰器与属性装饰器

TypeScript阿木 发布于 2025-05-28 5 次阅读


TypeScript 方法装饰器与属性装饰器详解

在TypeScript中,装饰器是一种特殊类型的声明,它能够被附加到类声明、方法、访问符、属性或参数上。装饰器提供了一种简单的方式来修改或增强类或类的成员的行为。本文将围绕TypeScript中的方法装饰器和属性装饰器进行深入探讨。

TypeScript装饰器是ES7中提出的一个特性,它允许开发者在不修改原有代码结构的情况下,通过注解的方式对类或类成员进行扩展。装饰器在TypeScript中主要分为三类:类装饰器、方法装饰器和属性装饰器。

方法装饰器

方法装饰器用于装饰类中的方法。它会在目标方法被调用之前或之后执行一些操作。方法装饰器接收三个参数:装饰目标、装饰目标的属性描述符和“应用上下文”。

以下是一个简单的示例,展示如何使用方法装饰器:

typescript
function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Method ${propertyKey} called with arguments:`, args);
return originalMethod.apply(this, args);
};
return descriptor;
}

class Calculator {
@logMethod
add(a: number, b: number): number {
return a + b;
}
}

const calc = new Calculator();
calc.add(5, 3); // 输出: Method add called with arguments: [ 5, 3 ]

在上面的示例中,`logMethod`装饰器会在`Calculator`类的`add`方法被调用之前打印出方法的名称和参数。

属性装饰器

属性装饰器用于装饰类中的属性。它可以在属性被赋值之前或之后执行一些操作。属性装饰器接收两个参数:装饰目标(通常是类)和属性名。

以下是一个简单的示例,展示如何使用属性装饰器:

typescript
function logProperty(target: any, propertyName: string) {
Object.defineProperty(target, propertyName, {
set(value: any) {
console.log(`Property ${propertyName} set to`, value);
}
});
}

class Person {
@logProperty
name: string;
}

const person = new Person();
person.name = 'Alice'; // 输出: Property name set to Alice

在上面的示例中,`logProperty`装饰器会在`Person`类的`name`属性被赋值时打印出属性名和值。

装饰器组合

在实际应用中,我们可能会需要将多个装饰器组合使用。TypeScript允许我们将多个装饰器应用于同一个目标,装饰器的执行顺序是从右到左。

以下是一个组合装饰器的示例:

typescript
function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log('Method decorator applied');
}

function logProperty(target: any, propertyName: string) {
console.log('Property decorator applied');
}

class Calculator {
@logMethod
@logProperty
add(a: number, b: number): number {
return a + b;
}
}

const calc = new Calculator();
calc.add(5, 3); // 输出: Method decorator applied

在这个例子中,`logMethod`装饰器会在`logProperty`装饰器之前执行。

装饰器工厂

装饰器工厂是一个函数,它返回一个装饰器函数。这种模式允许我们动态地创建装饰器。

以下是一个装饰器工厂的示例:

typescript
function createLogDecorator(logType: 'method' | 'property') {
return function(target: any, propertyName: string, descriptor: PropertyDescriptor) {
if (logType === 'method') {
console.log('Method decorator applied');
} else if (logType === 'property') {
console.log('Property decorator applied');
}
};
}

class Calculator {
@createLogDecorator('method')
add(a: number, b: number): number {
return a + b;
}

@createLogDecorator('property')
name: string;
}

const calc = new Calculator();
calc.add(5, 3); // 输出: Method decorator applied

在这个例子中,`createLogDecorator`函数根据传入的`logType`参数返回不同的装饰器函数。

总结

TypeScript中的方法装饰器和属性装饰器为开发者提供了一种强大的方式来扩展和增强类或类成员的行为。通过装饰器,我们可以在不修改原有代码的情况下,对类或类成员进行灵活的扩展。本文对方法装饰器和属性装饰器进行了详细的介绍,并通过示例展示了如何使用它们。希望这篇文章能够帮助读者更好地理解TypeScript装饰器的使用。