LoginSignup
10
9

More than 3 years have passed since last update.

TypeScript: オブジェクトのメソッド一覧を取得する関数 getMethods()

Last updated at Posted at 2019-11-19

オブジェクトのメソッド名を配列で返す関数を作ったので紹介します。

関数の仕様

オブジェクトのメソッド名を配列で返す関数とは、どんな関数かというと、オブジェクトのプロパティの中から、関数だけを抽出し、その関数名を返すというものです。

例えば、次のサンプルコードのように、非関数のpropertyと関数のmethodを持ったオブジェクトを渡すと、['method']を返します:

getMethods({
    property: 1,
    method() {},
})
// Output: ['method']

クラスのインスタンスにも適用可能です:

class MyClass {
    property = 1
    method() {}
}
getMethods(new MyClass())
// Output: ['method']

継承している場合、親クラスのメソッドも再帰的に探してリストアップします:

class A {
    methodA() {}
}
class B extends A {
    methodB() {}
}
class C extends B {
    methodC() {}
}
getMethods(new C())
// Output: ['methodC', 'methodB', 'methodA']

ゲッターやセッターはメソッド一覧から除外されます:

getMethods({
    get getter() {},
    set setter(value) {},
})
// Output: []

オブジェクトのメソッド名一覧を返す関数の実装

関数の実装は次のようになります:

const getMethods = (obj: object): string[] => {
  const getOwnMethods = (obj: object) =>
    Object.entries(Object.getOwnPropertyDescriptors(obj))
      .filter(([name, {value}]) => typeof value === 'function' && name !== 'constructor')
      .map(([name]) => name)
  const _getMethods = (o: object, methods: string[]): string[] =>
    o === Object.prototype ? methods : _getMethods(Object.getPrototypeOf(o), methods.concat(getOwnMethods(o)))
  return _getMethods(obj, [])
}

動作確認

上の実装が、メソッドだけを返すかの動作確認です:

class Parent {
    parentMethod() {}
    parentArrowFunction = () => {}
    parentInstanceProperty = 1
    get parentGetter() {}
    set parentSetter(value) {}

    static parentStaticMethod() {}
    static parentStaticArrowFunction = () => {}
    static parentStaticProperty = 1
    static get parentStaticGetter() {}
    static set parentStaticSetter(value) {}
}

Parent.prototype.parentPrototypeProperty = 1

class Foo extends Parent {
    childMethod() {}
    childArrowFunction = () => {}
    childInstancePropetry = 1
    get childGetter() {}
    set childSetter(value) {}

    static childStaticMethod() {}
    static childStaticArrowFunction = () => {}
    static childStaticProperty = 1
    static get childStaticGetter() {}
    static set childStaticSetter(value) {}
}

Foo.prototype.childPrototypeProperty = 1

console.log(getMethods(new Foo))
// Output:
[
  'parentArrowFunction',
  'childArrowFunction',
  'childMethod',
  'parentMethod'
]

関連資料

10
9
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
10
9