TypeScript 裝飾子是一種特殊的宣告,可以被附加到類聲明、函式、屬性或參數上。裝飾子使用 @ 表示符,後面跟著裝飾的名稱。雖然裝飾子是 TypeScript 的一個功能,但實際上它們是 ES7 (ECMAScript 2016) 的一個提案,TypeScript 已將它們加入。
要在 TypeScript 中使用裝飾子,我們需要在 tsconfig.json 文件中啟用 experimentalDecorators 設定。
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}
function simpleDecorator(target: any) {
    console.log("simpleDecorator called.");
}
@simpleDecorator
class MyClass { }
當上面的代碼運行時,simpleDecorator 函數將會被執行,輸出 "simpleDecorator called."。它證明了裝飾子是在宣告時運行的。
裝飾子是 TypeScript 的一個強大功能,在類、函式或屬性上添加特定的行為或邏輯。要使用它,首先需要在 tsconfig.json 中啟用實驗性設定。透過簡單的範例,我們看到裝飾子是如何運作的。在後續的部分中,我們將進一步探索裝飾子和它們的使用案例。
TypeScript 的裝飾子是一種特殊的宣告,可用於類、方法、訪問器、屬性或參數。它可以用來修改或增加它們的行為。
以下是一些 TypeScript 裝飾子的基本示例:
基本的類裝飾子:
function sealed(target: Function) {
    Object.seal(target);
    Object.seal(target.prototype);
}
@sealed
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
}
此裝飾子會鎖住類別,使其無法被擴展。
方法裝飾子:
function enumerable(value: boolean) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.enumerable = value;
    };
}
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    @enumerable(false)
    greet() {
        return "Hello, " + this.greeting;
    }
}
此裝飾子設定方法的 enumerable 屬性。
訪問器裝飾子:
function configurable(value: boolean) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.configurable = value;
    };
}
class Point {
    private _x: number;
    private _y: number;
    constructor(x: number, y: number) {
        this._x = x;
        this._y = y;
    }
    @configurable(false)
    get x() {
        return this._x;
    }
    @configurable(false)
    get y() {
        return this._y;
    }
}
此裝飾子使訪問器的 configurable 屬性為 false。
function format(formatString: string) {
    return function (target: any, propertyKey: string) {
        // 將格式化字符串存儲在反映元數據中
    };
}
class Greeter {
    @format("Hello, %s")
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return this.greeting;
    }
}
這是一個簡單的屬性裝飾子範例,它用於添加元數據。
參數裝飾子:
function logParameter(target: Object, propertyKey: string, parameterIndex: number) {
    const metadataKey = `__log_${propertyKey}_parameters`;
    if (Array.isArray(target[metadataKey])) {
        target[metadataKey].push(parameterIndex);
    }
    else {
        target[metadataKey] = [parameterIndex];
    }
}
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet(@logParameter name: string) {
        return "Hello " + name + ", " + this.greeting;
    }
}
此裝飾子可以用來記錄方法的參數,並在調用方法時使用。
裝飾子提供了一種非常彈性的方式來修改或擴充類、方法、存取器、屬性和靜態方法的行為。透過適當地應用裝飾子,開發者可以更方便地實現如加載、記錄、驗證等各種功能。