カスタム TypeScript デコレータを作成する方法

デコレータは、実行時にクラス、メソッド、プロパティ、またはパラメータを変更できる TypeScript の機能です。メタプログラミング機能を提供する特別な関数です。TypeScript では、デコレータは Angular などのフレームワークで機能強化のためによく使用されます。この記事では、カスタム デコレータを作成する方法を段階的に説明します。

TypeScript のデコレータの種類

TypeScript には主に 4 つのタイプのデコレータがあります。

  • クラスデコレータ
  • メソッドデコレータ
  • アクセサデコレータ
  • 不動産デコレーター

TypeScript でデコレータを有効にする

TypeScript プロジェクトでデコレータを使用するには、tsconfig.json ファイルで experimentalDecorators オプションを有効にする必要があります。

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

クラスデコレータの作成

クラス デコレータは、クラスのコンストラクターに適用されます。クラスにメタデータや機能を追加する場合に便利です。以下に、単純なクラス デコレータを作成する方法の例を示します。

function logClass(constructor: Function) {
  console.log(`Class ${constructor.name} is created`);
}

@logClass
class Person {
  constructor(public name: string) {}
}

const person = new Person("John");
// Output: Class Person is created

メソッドデコレータの作成

メソッド デコレータはクラス メソッドに適用されます。メソッド デコレータを使用すると、メソッドの動作を変更したり監視したりできます。以下は、メソッドの実行をログに記録するメソッド デコレータの例です。

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

  descriptor.value = function (...args: any[]) {
    console.log(`Method ${propertyKey} is called with arguments:`, args);
    return originalMethod.apply(this, args);
  };

  return descriptor;
}

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

const calc = new Calculator();
calc.add(2, 3); 
// Output: Method add is called with arguments: [2, 3]

プロパティデコレータの作成

プロパティ デコレータは、プロパティを監視または変更するために使用できます。以下は、プロパティ デコレータを使用してプロパティにデフォルト値があることを確認する例です。

function defaultValue(value: any) {
  return function (target: any, propertyKey: string) {
    let propertyValue = value;

    const getter = function () {
      return propertyValue;
    };

    const setter = function (newValue: any) {
      propertyValue = newValue || value;
    };

    Object.defineProperty(target, propertyKey, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true,
    });
  };
}

class User {
  @defaultValue('Anonymous')
  name!: string;
}

const user = new User();
console.log(user.name); // Output: Anonymous
user.name = 'Alice';
console.log(user.name); // Output: Alice

パラメータデコレータの作成

パラメータ デコレータはメソッドのパラメータに適用されます。検証や引数のログ記録などのタスクに役立ちます。パラメータ デコレータの例を次に示します。

function logParameter(target: any, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} is being decorated`);
}

class Vehicle {
  drive(@logParameter speed: number) {
    console.log(`Driving at speed ${speed}`);
  }
}

const vehicle = new Vehicle();
vehicle.drive(50);
// Output: Parameter at index 0 in method drive is being decorated

結論

TypeScript のデコレータは、クラス、メソッド、プロパティの機能を強化および拡張できる強力なメタプログラミング機能を提供します。カスタム デコレータを使用すると、再利用可能で効率的で整理されたコード構造を作成できます。このガイドでは、クラス、メソッド、プロパティ、パラメーターなど、さまざまな種類のデコレータの作成について説明しました。