TypeScript 装饰器详解

403 阅读2分钟

TypeScript 装饰器详解

装饰器是 TypeScript 中一种特殊的声明,可以附加到类声明、方法、访问符、属性或参数上。本文将详细介绍 TypeScript 中的各种装饰器,包括它们的调用时机、接受的参数和返回内容。

类装饰器

调用时机:类装饰器在类实例化之前被调用。

参数:类的构造函数作为唯一参数。

返回内容:如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。

代码示例:

function classDecorator<T extends { new (...args: any[]): {} }>(constructor: T) {
  return class extends constructor {
    newProperty = "new property";
  };
}

@classDecorator
class MyClass {
  property = "property";
}

const myInstance = new MyClass();
console.log(myInstance.property); // "property"
console.log(myInstance.newProperty); // "new property"

为什么class已经被替换, console.log(myInstance.property); // "property" ?

当我们使用 @classDecorator 装饰 MyClass 时,实际上是用 classDecorator 函数返回的新类替换了原始的 MyClass。但是,由于新类继承了原始类,所以它们之间存在原型链关系。

方法装饰器

调用时机:方法装饰器在方法被调用时执行。

参数:1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2. 成员的名字。3. 成员的属性描述符。

返回内容:如果方法装饰器返回一个值,它会被用作方法的属性描述符。

代码示例:

function methodDecorator(
  target: Object,
  propertyKey: string,
  descriptor: PropertyDescriptor
) {
  console.log("Method Decorator");
}

class MyClass {
  @methodDecorator
  myMethod() {
    console.log("MyMethod");
  }
}

const myInstance = new MyClass();
myInstance.myMethod(); // "Method Decorator" and "MyMethod"

访问器装饰器

调用时机:访问器装饰器在访问器(getter 或 setter)被调用时执行。

参数:1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2. 成员的名字。3. 成员的属性描述符。

返回内容:如果访问器装饰器返回一个值,它会被用作方法的属性描述符。

代码示例:

function accessorDecorator(
  target: Object,
  propertyKey: string,
  descriptor: PropertyDescriptor
) {
  descriptor.enumerable = false;
}

class MyClass {
  private _value: number;

  constructor(value: number) {
    this._value = value;
  }

  @accessorDecorator
  get value(): number {
    return this._value;
  }
}

const myInstance = new MyClass(42);
console.log(myInstance.value); // 42

属性装饰器

调用时机:属性装饰器在属性被访问或修改时执行。

参数:1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2. 成员的名字。

返回内容:属性装饰器的返回值会被忽略。

代码示例:

function propertyDecorator(target: Object, propertyKey: string) {
  console.log("Property Decorator");
}

class MyClass {
  @propertyDecorator
  myProperty = "MyProperty";
}

const myInstance = new MyClass();
console.log(myInstance.myProperty); // "Property Decorator" and "MyProperty"

参数装饰器

调用时机:参数装饰器在方法被调用时执行,位于方法装饰器之前。

参数:1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。2. 成员的名字。3. 参数在函数参数列表中的索引。

返回内容:参数装饰器的返回值会被忽略。

代码示例:

function parameterDecorator(
  target: Object,
  propertyKey: string,
  parameterIndex: number
) {
  console.log("Parameter Decorator");
}

class MyClass {
  myMethod(@parameterDecorator value: number) {
    console.log("MyMethod");
  }
}

const myInstance = new MyClass();
myInstance.myMethod(42); // "Parameter Decorator" and "MyMethod"