发布于 2026-01-06 6 阅读
0

TypeScript 函数式装饰器及其用例、可绑定属性、依赖注入、监视装饰器验证、AJAX 服务、数据加载

TypeScript 函数式装饰器及其使用案例

可约束财产

依赖注入

手表装饰师

验证

AJAX 服务

数据加载

在编程中,装饰器通常用于为方法、变量或类添加一些额外的含义/功能。

我在使用 Spring Boot 开发时经常用到装饰器。目前我正在学习 TypeScript,装饰器深深吸引了我。以下是我使用 TypeScript 装饰器来处理函数的一个简单示例。

假设有一个 Human 类,它维护着一个名为 stamina 的属性,该属性会被 run 和 rest 方法操作。我们需要在 run 和 rest 这两个操作前后分别获取 stamina 的值。我提供了使用和不使用装饰器的代码片段。

装饰器之前的代码

class Human {
    stamina: number;
    constructor(stamina: number) {
        this.stamina = stamina;
    }

    run(requiredStamina: number): number {
        return (this.stamina -= requiredStamina);
    }

    rest(addedStamina: number): number {
        return (this.stamina += addedStamina);
    }
}

const human = new Human(10);
console.log(`Stamina before run: ` + human.stamina);
human.run(1);
console.log(`Stamina after run: ` + human.stamina);
console.log(`Stamina before rest: ` + human.stamina);
human.rest(12);
console.log(`Stamina after rest: ` + human.stamina);
console.log(`Stamina before run: ` + human.stamina);
human.run(20);
console.log(`Stamina after run: ` + human.stamina);
// Stamina before run: 10
// Stamina after run: 9
// Stamina before rest: 9
// Stamina after rest: 21
// Stamina before run: 21
// Stamina after run: 1
Enter fullscreen mode Exit fullscreen mode

上面的代码看起来不错,但很快文件就会充斥着大量样板代码。

使用装饰器编写代码

class Human {
    stamina: number;
    constructor(stamina: number) {
        this.stamina = stamina;
    }

    @log
    run(requiredStamina: number): number {
        return (this.stamina -= requiredStamina);
    }

    @log
    rest(addedStamina: number): number {
        return (this.stamina += addedStamina);
    }
}
function log(
    target: Object,
    propertyKey: string,
    descriptor: TypedPropertyDescriptor<any>
) {
    const originalMethod = descriptor.value; // save a reference to the original method

    // NOTE: Do not use arrow syntax here. Use a function expression in
    // order to use the correct value of `this` in this method (see notes below)
    descriptor.value = function (...args: any[]) {
        // pre
        console.log(`Stamina before ${propertyKey}: ` + args);
        // run and store result
        const result = originalMethod.apply(this, args);
        // post
        console.log(`Stamina after ${propertyKey}: ` + result);
        // return the result of the original method (or modify it before returning)
        return result;
    };

    return descriptor;
}

const human = new Human(10);
human.run(1);
human.rest(12);
human.run(20);
// Stamina before run: 1
// Stamina after run: 9
// Stamina before rest: 12
// Stamina after rest: 21
// Stamina before run: 20
// Stamina after run: 1
Enter fullscreen mode Exit fullscreen mode

我在代码片段中添加了注释,解释了装饰器中的数据流!简而言之,装饰器会在函数调用之前执行,并且可以访问函数的参数和返回值,供装饰器使用。

装饰器通常有很多用例。请在评论中告诉我一些有趣的用例,或者通过radnerus93联系我

文章来源:https://dev.to/radnerus/typescript-function-decorators-w-usecases-1a8g