角待ちは対空

おもむろガウェイン

TypeScript2.2でのmixinサポート

TS2.2 では Improved support for mixins and composable classes と称してmixin への対応が入る。 とは言え mixin などのキーワードが入るわけではなく、あくまで型サポートが入ることにより関数での mixin の実現が容易になる程度である。

github.com

The result is that you can write a function that

  1. takes a constructor
  2. declares a class that extends that constructor
  3. adds members to that new class
  4. and returns the class itself.

どういうことができるようになると以下の Debuggable 関数は constractor() を持つ任意のオブジェクトに debug()debugCount というプロパティを追加する( debugCount は特に意味は無いけど例示のため )。

type Constructable<T> = new(...args: any[]) => T; // => constractor がある何かしらのオブジェクト

function Debuggable<BC extends Constructable<object>>(Base: BC) { // => object 型も今回追加
    return class extends Base {
        debugCount: number = 0;   // => プロパティも生やせる
        constructor(...args: any[]) { // => constructorも書き換えられる
            super(...args);
        }
        debug(): void { // => メソッドも追加できる
            let propNames: string[] = [];
            let o = this;
            while (o) {
                propNames = propNames.concat(Object.getOwnPropertyNames(o));
                o = Object.getPrototypeOf(o);
            }
            propNames.forEach((v) => {
                console.log(v, "=>", (<any>this)[v]);
            })

            this.debugCount = this.debugCount + 1;
        }
    };
}

class N {
    x = 1;
    y = 2;
}

const DebuggableN = Debuggable(N); // => N を Debuggable にする

let n = new DebuggableN;

n.debug() // => debug() が生える
console.log("debugCount", n.debugCount); // => debugCount も生える

結構何やってるのか見づらいという印象だけど変にキーワード入れるよりは素朴でいいかもしれない。