TypeScriptのクラスのメソッド名をUnion Typeで取得する方法

TypeScriptのクラスのメソッド名をUnion Typeで取得する方法
この記事のポイント
  • 完全にTypeScriptでクラスのメソッド名をUnion Typeで取得するのは難しい
  • Function型かany型を使うことでメソッド名をUnion Typeで取得できる

TypeScriptのクラスのメソッドをUnion Typeで取得したかったのでで調べてみました。
例えば下記のようなクラスがあるとします。

class Example {
method1() {}
method2() {}
}

このクラスから下記のような型を取得したい場合を想定します。

'method1' | 'method2'

まず結論から話すと、TypeScriptの型システムでは、クラスのメソッド名をUnion Typeで完全に取得することは難しいようです。
取得はできるもののFunction型を使うかany型を使う必要があります。

Function型を使う方法

type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? K : never
}[keyof T]
type MethodNames = FunctionPropertyNames<Example> // "method1" | "method2"

Function型はTypeScriptで使用することを推奨してしていないので別の方法を探します。

any型を使う方法

Function型を使わない方法をGithub Pilotで調べて見たところ下記のような回答が来ました。

このコードでは、Function型の代わりに(…args: any[]) => any型を使用しています。これにより、任意の引数を取り、任意の値を返す関数のみを対象とすることができます。

type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never
}[keyof T]
type MethodNames = FunctionPropertyNames<Example> // "method1" | "method2"

この方法ではFunction型は使わないもののanyを使わない方法も調べてみましたが、見つかりませんでした。

結論

最後にany型を使わない方法も調べてみると下記のような回答が来ました。

完全にanyを避けることは、一部のケースでは難しいかもしれません。特に、関数の引数や戻り値の型が動的である場合や、ライブラリのAPIがany型を要求している場合などです。
しかし、TypeScriptの強力な型推論機能を活用することで、多くの場合でanyの使用を避けることが可能です。具体的には、変数や関数の戻り値の型を明示的に指定する代わりに、TypeScriptに型推論を任せることができます。
また、unknown型を使用することで、anyの代わりに型安全な代替手段を提供することも可能です。unknown型はany型と同様に任意の値を受け入れますが、unknown型の値を他の型の値として使用する前に型チェックを行う必要があります。
したがって、anyを全く使わないことは不可能ではありませんが、そのためには適切な型推論や型チェックを行う必要があります。

TypeScriptでクラスのメソッド名をUnion Typeで取得するには現状ではFunction型かany型を使うしかなく、Lintで引っかかる可能性があるので注意が必要です。

その場合は、Lintから除外して対応することになりそうです。

Related Posts

Collaborative Innovation
for Your Growth

合同会社コードコネクトはフロントエンドを中心としたWeb開発を得意としています。
このようなシステム開発にご興味のある方、またはお困りの方はお気軽にお問い合わせください。

  • JamstackをベースとしたWebサイトの構築
  • Reactなどを用いたアプリケーションの開発
  • 運用に耐えられるメンテナンス性を考慮したプロダクト開発
  • モダンで運用可能な開発環境の構築