BLOGサブスレッドの日常

2023.05.28

TypeScriptで無名クラスが使える件

tama

IDEの補完無しではコードを書けない体になっちゃいました。tama です。

JavaScript や TypeScript では無名関数ってよく使いますよね。

window.addEventListener('beforeunload', function (e: BeforeUnloadEvent) {
   ...
});

こういうやつです。

const [valueA, valueB] = (() => {
  let valueA = 0, valueB = 100;
  // valueA, valueB を算出する演算があって let にせざるを得ないけれど使うときは const でいい場合など
  return [valueA, valueB];
})();

こんな使い方もします。

これと同じノリで、無名クラスを書くこともできます。

const instance = new (class {
  readonly key = '';

  get property() {
    return 0; // 何かの値とか
  }

  method() {
    // 何か処理とか
  }
})();

こんな感じです。
これだけだと嬉しみがあまりわからないかもしれませんが、継承を組み合わせると、このインスタンスにだけメソッドをひとつ追加したい、なんて場合に重宝する…かもしれません。

const instance = new (class extends Array<SomeType> {
  // Set風の has()
  has(element: SomeType) {
    return this.indexOf(element) >= 0;
  }
})();

もっとも至る所で同じコードを書くことになるのなら、Array 自体を拡張してしまったほうが便利です。

declare global {
  interface Array<T> {
    has(element: T): boolean;
  }
}

Array.prototype.has = function <T>(element: T): boolean {
  return this.indexOf(element) >= 0;
};

どっちも evil なコードだと言われればそうなのかもしれません。
「できる」ことと「していい」こと、「すべき」ことは別なので、プロジェクトのコーディングルールに従うべきですが、無名クラスも使えることを知っていると、何かのときに役に立つかもしれない、、っていう共有でした。

この記事を書いた人

tama