TypeScript でデコレータを使用する方法

TypeScript のデコレータは、開発者がクラス、メソッド、プロパティ、およびパラメータに追加機能を追加できるようにする強力な機能です。デコレータを使用すると、既存のコードの実際の構造を変更せずに、その動作を変更できます。このガイドでは、わかりやすい例を使用して、TypeScript でデコレータを使用する方法について説明します。

デコレータとは何ですか?

デコレータは、クラス、メソッド、プロパティ、またはパラメータに適用できる特別な関数です。これらは実行時に呼び出され、開発者が宣言的にコードに注釈を付けたり変更したりできるようにします。TypeScript プロジェクトでデコレータを有効にするには、tsconfig.json ファイルで experimentalDecorators フラグを true に設定する必要があります。

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

デコレータを使用するには、TypeScript コンパイラがデコレータを認識するように設定する必要があります。これは、tsconfig.json ファイルで experimentalDecorators フラグを true に設定することで実行できます。

{
  "compilerOptions": {
    "target": "ES6",
    "experimentalDecorators": true
  }
}

デコレータを有効にすると、プロジェクト全体で使用できるようになります。

クラスデコレータの作成

クラス デコレータはクラス宣言に適用され、クラス定義を変更または置換するために使用できます。クラス デコレータは、@ シンボルを使用して、デコレートするクラスのすぐ上で宣言されます。

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

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

const person = new Person('Alice');

この例では、LogClass デコレータは、Person クラスが作成されたときにメッセージをログに記録します。デコレータは、デコレートされるクラスのコンストラクターという単一の引数を取る関数として定義されます。

メソッドデコレータ

メソッド デコレータはクラス内のメソッドに適用されます。これにより、開発者はメソッド呼び出しをインターセプトしたり、メソッドの動作を変更したり、メソッドの実行前または実行後に追加の操作を実行したりできるようになります。

function LogMethod(target: Object, 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): number {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3);

ここで、LogMethod デコレータは、add メソッドが呼び出されるたびに、メソッド名とその引数をログに記録します。元のメソッドを、元のメソッドに委任する前にログ記録を実行する新しい関数にラップします。

不動産デコレーター

プロパティ デコレータは、クラス プロパティの動作を監視または変更するために使用されます。メソッド デコレータとは異なり、プロパティ値自体にはアクセスできませんが、プロパティにメタデータを追加できます。

function ReadOnly(target: Object, propertyKey: string) {
  Object.defineProperty(target, propertyKey, {
    writable: false
  });
}

class Book {
  @ReadOnly
  title: string = 'TypeScript Guide';
}

const myBook = new Book();
myBook.title = 'New Title'; // This will cause an error in strict mode

この例では、ReadOnly デコレータが Book クラスの title プロパティに適用され、writablefalse に設定されて読み取り専用になります。

パラメータデコレータ

パラメータ デコレータは、メソッド パラメータに注釈を付けたり変更したりするために使用されます。パラメータ デコレータは、ターゲット オブジェクト、メソッド名、パラメータ インデックスの 3 つの引数を受け取ります。

function LogParameter(target: Object, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter in position ${parameterIndex} at ${propertyKey} method is decorated.`);
}

class UserService {
  greet(@LogParameter message: string): void {
    console.log(message);
  }
}

const userService = new UserService();
userService.greet('Hello, TypeScript!');

この例では、LogParameter デコレータが、UserService クラスの greet メソッドの message パラメータに適用されます。デコレータは、デコレートされるパラメータに関する情報をログに記録します。

結論

TypeScript のデコレータは、コードの構造を変更せずにコード機能を強化する強力な手段を提供します。クラス、メソッド、プロパティ、およびパラメータのデコレータを活用することで、開発者はプロジェクト全体に再利用可能な機能を簡単に追加できます。このガイドで提供されている例を使用すると、TypeScript でデコレータの使用を簡単に開始できます。