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"