ZetCode

TypeScript 装饰器

最后修改时间:2025年3月3日

TypeScript 中的装饰器是一种特殊的声明,可以附加到类、方法、属性或参数上。它们提供了一种添加元数据或修改这些元素行为的方式。本教程将通过实际示例深入探讨装饰器。

基本定义

装饰器是前面带有 @ 符号的函数。根据它们装饰的内容,它们会以特定的参数被调用。TypeScript 支持类、方法、属性和参数装饰器。

类装饰器

类装饰器应用于类的构造函数。它可以观察、修改或替换类定义。此示例日志记录类名。

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

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

// Output: Class: User

LogClass 装饰器在定义类时日志记录类名。它接收构造函数作为其参数。

方法装饰器

方法装饰器应用于方法定义。它们可以修改或替换方法。此示例日志记录方法调用。

method_decorator.ts
function LogMethod(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log(`Method called: ${key}`);
}

class Calculator {
    @LogMethod
    add(a: number, b: number): number {
        return a + b;
    }
}

const calc = new Calculator();
calc.add(2, 3);  // Output: Method called: add

LogMethod 装饰器在调用方法时日志记录方法名。它接收目标对象、方法名和属性描述符。

属性装饰器

属性装饰器应用于属性声明。它们可以观察或修改属性。此示例日志记录属性名。

property_decorator.ts
function LogProperty(target: any, key: string) {
    console.log(`Property: ${key}`);
}

class Product {
    @LogProperty
    name: string;

    constructor(name: string) {
        this.name = name;
    }
}

// Output: Property: name

LogProperty 装饰器在定义类时日志记录属性名。它接收目标对象和属性名。

参数装饰器

参数装饰器应用于方法的参数。它们可以观察或修改参数。此示例日志记录参数名。

parameter_decorator.ts
function LogParameter(target: any, key: string, index: number) {
    console.log(`Parameter: ${key}[${index}]`);
}

class Greeter {
    greet(@LogParameter name: string): void {
        console.log(`Hello, ${name}!`);
    }
}

// Output: Parameter: greet[0]

LogParameter 装饰器在定义方法时日志记录参数名和索引。它接收目标对象、方法名和参数索引。

访问器装饰器

访问器装饰器应用于 getter 或 setter 方法。它们可以修改或替换访问器。此示例日志记录访问器调用。

accessor_decorator.ts
function LogAccessor(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log(`Accessor called: ${key}`);
}

class Account {
    private _balance: number = 0;

    @LogAccessor
    get balance(): number {
        return this._balance;
    }

    set balance(value: number) {
        this._balance = value;
    }
}

const acc = new Account();
acc.balance = 100;  // Output: Accessor called: balance

LogAccessor 装饰器在调用访问器时日志记录访问器名。它接收目标对象、访问器名和属性描述符。

装饰器工厂

装饰器工厂是返回装饰器的函数。它们允许自定义装饰器行为。此示例创建了一个可配置的日志装饰器。

factory_decorator.ts
function LogFactory(message: string) {
    return function(target: any, key: string, descriptor: PropertyDescriptor) {
        console.log(`${message}: ${key}`);
    };
}

class Logger {
    @LogFactory("Method called")
    log(message: string): void {
        console.log(message);
    }
}

const logger = new Logger();
logger.log("Test");  // Output: Method called: log

LogFactory 函数返回一个日志记录自定义消息的装饰器。它允许动态配置装饰器行为。

多个装饰器

多个装饰器可以应用于同一个元素。它们按相反的顺序执行。此示例演示了多个装饰器。

multiple_decorators.ts
function First(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log("First decorator");
}

function Second(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log("Second decorator");
}

class Example {
    @First
    @Second
    method(): void {
        console.log("Method called");
    }
}

// Output: Second decorator
// Output: First decorator

FirstSecond 装饰器应用于同一个方法。它们按相反的顺序执行,Second 先执行。

最佳实践

来源

TypeScript 装饰器文档

本教程通过实际示例涵盖了 TypeScript 装饰器。使用装饰器来增强您的 TypeScript 应用程序,实现元数据和行为修改。

作者

我叫 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面有十多年的经验。

列出所有 TypeScript 教程