LoginSignup
0
0

More than 1 year has passed since last update.

TypeScriptで宣言と定義を分けずに拡張メソッドを書く

Last updated at Posted at 2022-01-29

ググって見つかる記事を参考にすると、interface + prototypeでメソッドの宣言と定義を2回に分けなければならず面倒。
けど、こんな感じでかけば定義と宣言を同時にできて楽。

適当なファイルにmixin関数を用意する

function mixin(base: { prototype: any[] }, derived: object) {
    Object.getOwnPropertyNames(derived).forEach((propertyName) => {
        Object.defineProperty(base.prototype, propertyName as (keyof (typeof derived)), {
            // @ts-ignore
            value: derived[propertyName],
            writable: true
        });
    });
}

拡張部分

Arrayクラスに対してget, head, lastを定義する例。

prototype.ts
export {}

type Super<T> = Array<T>;
type ArrayExClass = typeof ArrayEx;
declare global {
    interface Array<T> extends ArrayExClass {}
}

const ArrayEx = {
    get: function <T>(this: Super<T>, index: number): T {
        return this[index];
    },
    head: function <T>(this: Super<T>): T {
        return this.get(0);
    },
    last: function <T>(this: Super<T>): T {
        return this.get(this.length - 1);
    },
}
mixin(Array, ArrayEx)
  • prototypeに1個1個代入していくパターンに比べて、使いまわしが聞く。そのためmixinのような動きに近いこともできる。
  • self type annotationみたいな制限もthisの型を調整すればできそう。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0