fe-interview icon indicating copy to clipboard operation
fe-interview copied to clipboard

[TypeScript] 第1545天 在TypeScript中如何创建和使用装饰器?

Open haizhilin2013 opened this issue 2 years ago • 1 comments
trafficstars

第1545天 在TypeScript中如何创建和使用装饰器?

3+1官网

我也要出题

haizhilin2013 avatar Jul 08 '23 20:07 haizhilin2013

在TypeScript中,装饰器(Decorators)是一种特殊类型的声明,它能够附加到类声明、方法、访问器、属性或参数上,可以修改类的行为。装饰器使用 @expression 这种形式来声明,expression 必须是一个在运行时可以调用的函数。装饰器主要有以下几种类型:

  1. 类装饰器 (Class Decorator)
  2. 方法装饰器 (Method Decorator)
  3. 访问器装饰器 (Accessor Decorator)
  4. 属性装饰器 (Property Decorator)
  5. 参数装饰器 (Parameter Decorator)

下面是每种装饰器的详细使用方法:

1. 类装饰器

类装饰器应用于类构造函数,可以用来监视、修改或替换类定义。

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

@classDecorator
class MyClass {
    property = "property";
    hello: string;
    constructor(m: string) {
        this.hello = m;
    }
}

console.log(new MyClass("world"));

2. 方法装饰器

方法装饰器声明在一个方法的前面,可以用来修改方法的定义、添加额外的逻辑等。

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

    descriptor.value = function (...args: any[]) {
        console.log("Method called: " + propertyKey);
        return originalMethod.apply(this, args);
    };

    return descriptor;
}

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

const myInstance = new MyClass();
myInstance.myMethod();

3. 访问器装饰器

访问器装饰器应用于属性的 getter 或 setter 方法,可以用来修改访问器的行为。

function accessorDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalGet = descriptor.get;

    descriptor.get = function () {
        console.log(`Getting value of ${propertyKey}`);
        return originalGet?.apply(this);
    };

    return descriptor;
}

class MyClass {
    private _name: string = "default";

    @accessorDecorator
    get name() {
        return this._name;
    }

    set name(value: string) {
        this._name = value;
    }
}

const myInstance = new MyClass();
console.log(myInstance.name);

4. 属性装饰器

属性装饰器声明在一个属性声明之前,用于修改属性的元数据。

function propertyDecorator(target: any, propertyKey: string) {
    console.log(`Property ${propertyKey} decorated`);
}

class MyClass {
    @propertyDecorator
    myProperty: string;

    constructor() {
        this.myProperty = "hello";
    }
}

const myInstance = new MyClass();
console.log(myInstance.myProperty);

5. 参数装饰器

参数装饰器声明在一个方法的参数前面,用于修改参数的元数据。 这个例子在 Typescript 4.7版本能够运行,5.0版本后报错了,原因待查看了。

function parameterDecorator(target: any, propertyKey: string, parameterIndex: number) {
    console.log(`Parameter ${parameterIndex} in method ${propertyKey} decorated`);
}

class MyClass {
    myMethod(@parameterDecorator param1: string) {
        console.log(param1);
    }
}

const myInstance = new MyClass();
myInstance.myMethod("hello");

总结

装饰器提供了一种强大的方式来扩展和修改类及其成员的行为。通过理解和使用不同类型的装饰器,可以在 TypeScript 中实现更加灵活和可维护的代码。

llccing avatar Jun 26 '24 08:06 llccing