【実践TypeScript】デコレータを使いこなす!効率的なコーディングテクニック解説

2023.08.05 に更新記事は 4 分で読めます
サムネイル画像

この記事ではTypeScriptのデコレータ(@)について分かりやすく説明していきたいと思います!

結論

デコレータはJavaScriptのクラスやメソッドに対して動的な機能を追加するための構文です。
ただ、TypeScriptでもその機能を活用することができます。

種類としては、クラスデコレータ、プロパティデコレータ、メソッドデコレータ、パラメータデコレータがあります。

それぞれを使い分けて効率的なコードを書きましょう!

TypeScriptのデコレータの種類

先程も紹介したように、TypeScriptのデコレータには4つの種類があります。

  • クラスデコレータ
  • プロパティデコレータ
  • メソッドデコレータ
  • パラメータデコレータ

それぞれのデコレータについて、具体的なコード例とともに説明していきますね。

クラスデコレータ

クラスデコレータはクラス宣言の直前に記述されるものです。

次のコード例では @sealed というクラスデコレータを作成しています。

function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;

  constructor(message: string) {
    this.greeting = message;
  }

  greet() {
    return "Hello, " + this.greeting;
  }
}

この例では @sealed デコレータは Greeter クラスに適用され、そのクラスとプロトタイプがシールド(変更不可)になります。

プロパティデコレータ

プロパティデコレータはクラスのプロパティ宣言の直前に記述されます。

以下のコード例では @format というプロパティデコレータを作成しています。

function format(formatString: string) {
  return function (target: any, propertyKey: string) {
    Object.defineProperty(target, propertyKey, {
      get: function () {
        return formatString.replace("%s", this[propertyKey]);
      },
    });
  };
}

class Greeter {
  @format("Hello, %s")
  greeting: string;

  constructor(message: string) {
    this.greeting = message;
  }
}

この例では @format デコレータは greeting プロパティに適用され、そのプロパティがアクセスされる際にフォーマットされた文字列が返されるようになります。

メソッドデコレータ

メソッドデコレータはクラスのメソッド宣言の直前に記述されます。

次のコード例では @enumerable というメソッドデコレータを作成しています。

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 デコレータは greet メソッドに適用され、そのメソッドが列挙可能かどうかを設定しています。

パラメータデコレータ

パラメータデコレータはクラスのメソッド宣言内のパラメータの直前に記述されます。

以下のコード例では @required というパラメータデコレータを作成しています。

function required(target: any, propertyKey: string, parameterIndex: number) {
  // パラメータが必須であることを示す処理を実装
}

class Greeter {
  greeting: string;

  constructor(@required message: string) {
    this.greeting = message;
  }
}

この例では @required デコレータは constructor メソッドの message パラメータに適用され、そのパラメータが必須であることを示しています。

TypeScriptのデコレータの使い方

illust

デコレータを使う際はまずデコレータの関数を定義し、その後でクラスやメソッド、プロパティ、パラメータに対して適用します。

また、複数のデコレータを適用することもできます。
その場合、デコレータは上から下へ順番に評価されて下から上へ順番に適用されます。

デコレータの実装にはデコレータファクトリ(デコレータ関数を返す関数)がよく使われます。
デコレータファクトリを使うことでデコレータに引数を渡すことができます。

まとめ

今回はTypeScriptのデコレータについて紹介しました。

デコレータはクラスやメソッド、プロパティ、パラメータに対して動的な機能を追加するための強力な構文です。
4つの種類のデコレータ(クラスデコレータ、プロパティデコレータ、メソッドデコレータ、パラメータデコレータ)を活用することでコードの可読性や効率性を向上させることができます。

プロフィールアイコン

Syuu

フロントエンドが好きなWEBエンジニア Next.js / React / TypeScript

SHARE