如何在 TypeScript 中使用装饰器

TypeScript 中的装饰器是一项强大的功能,它使开发人员能够向类、方法、属性和参数添加额外的功能。它们提供了一种在不改变现有代码实际结构的情况下修改其行为的方法。本指南将通过简单易懂的示例解释如何在 TypeScript 中使用装饰器。

什么是装饰器?

装饰器是可应用于类、方法、属性或参数的特殊函数。它们在运行时调用,允许开发人员以声明方式注释和修改代码。要在 TypeScript 项目中启用装饰器,必须在 tsconfig.json 文件中将 experimentalDecorators 标志设置为 true

在 TypeScript 中启用装饰器

要使用装饰器,必须配置 TypeScript 编译器以识别它们。这可以通过在 tsconfig.json 文件中将 experimentalDecorators 标志设置为 true 来实现。

{
  "compilerOptions": {
    "target": "ES6",
    "experimentalDecorators": true
  }
}

一旦启用装饰器,它们就可以在整个项目中使用。

创建类装饰器

类装饰器应用于类声明,可用于修改或替换类定义。类装饰器声明在它们所装饰的类的正上方,使用 @ 符号。

function LogClass(target: Function) {
  console.log(`Class ${target.name} is created.`);
}

@LogClass
class Person {
  constructor(public name: string) {}
}

const person = new Person('Alice');

在此示例中,LogClass 装饰器在创建 Person 类时记录一条消息。该装饰器被定义为一个函数,它接受一个参数:被装饰类的构造函数。

方法装饰器

方法装饰器应用于类中的方法。它们允许开发人员在方法执行之前或之后拦截方法调用、修改其行为或执行其他操作。

function LogMethod(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`Method ${propertyKey} is 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(2, 3);

此处,LogMethod 装饰器在调用 add 方法时记录方法名称及其参数。它将原始方法包装在一个新函数中,该新函数在委托给原始方法之前执行记录。

属性装饰器

属性装饰器用于观察或修改类属性的行为。与方法装饰器不同,它们无法访问属性值本身,但可以向属性添加元数据。

function ReadOnly(target: Object, propertyKey: string) {
  Object.defineProperty(target, propertyKey, {
    writable: false
  });
}

class Book {
  @ReadOnly
  title: string = 'TypeScript Guide';
}

const myBook = new Book();
myBook.title = 'New Title'; // This will cause an error in strict mode

在此示例中,ReadOnly 装饰器应用于 Book 类的 title 属性,通过将 writable 设置为 false 使其变为只读。

参数装饰器

参数装饰器用于注释或修改方法参数。它们接收三个参数:目标对象、方法名称和参数索引。

function LogParameter(target: Object, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter in position ${parameterIndex} at ${propertyKey} method is decorated.`);
}

class UserService {
  greet(@LogParameter message: string): void {
    console.log(message);
  }
}

const userService = new UserService();
userService.greet('Hello, TypeScript!');

在此示例中,LogParameter 装饰器应用于 UserService 类中 greet 方法的 message 参数。该装饰器记录有关被装饰参数的信息。

结论

TypeScript 中的装饰器提供了一种在不改变代码结构的情况下增强代码功能的强大方法。通过利用类、方法、属性和参数装饰器,开发人员可以轻松地在其项目中添加可重复使用的功能。借助本指南中提供的示例,您可以轻松开始在 TypeScript 中使用装饰器。