開発覚書はてな版

個人的な開発関連の備忘録

【TypeScript】reflect-metadataでMethodDecoratorを実装する

概要

  • reflect-metadataでMethodDecoratorを実装するサンプルです。
  • メソッドにメタデータを定義するケースです。

www.npmjs.com

実装方針

  • MethodDecorator を定義する。
  • 上記のMethodDecoratorをメソッドに指定したクラスを定義する。
  • 上記のクラスからMethodDecoratorを指定したメソッドを検出して実行する。

実行環境

  • Node.js - 10.x
  • Yarn - 1.17.x

使用ライブラリ

  • reflect-metadata - 0.1.x
  • TypeScript - 3.7.x

サンプルソース

execute.decorator.ts

import 'reflect-metadata';

export const EXECUTE_METADATA_KEY = '__method:execute__';

export function Execute(): MethodDecorator {
  return (target: object, propertyKey: string | symbol) => {
    Reflect.defineMetadata(EXECUTE_METADATA_KEY, '', target, propertyKey);
  };
}

execute.sample.ts

import { Execute } from './execute.decorator';

export class ExecuteSample {
  @Execute()
  exec(): void {
    console.log('ExecuteSample - exec');
  }
}

main.ts

import { EXECUTE_METADATA_KEY } from './execute.decorator';
import { ExecuteSample } from './execute.sample';
import 'reflect-metadata';

function exec(): void {
  const obj = new ExecuteSample();

  // 対象オブジェクトのプロパティ名、メソッド名の一覧を取得
  for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(obj))) {
    if (typeof obj[key] !== 'function') {
      continue;
    }
    if (!Reflect.getMetadataKeys(obj, key).some(m => m === EXECUTE_METADATA_KEY)) {
      continue;
    }
    obj[key]();
  }
}

exec();

実行結果

ExecuteSample - exec

サンプルソース一式

github.com

おわりに

  • 今回はマーカーとして、メタデータを使用してみました。
  • 動的に処理対象のメソッドを宣言したい場合にMethodDecoratorは便利です。