1. ホーム
  2. typescript

[解決済み] ジェネリック関数のTypescript ReturnType

2023-03-31 18:27:05

質問

新しい ReturnType TypeScript 2.8 は、特定の関数の戻り値の型を抽出することができる、本当に便利な機能です。

function foo(e: number): number {
    return e;
}

type fooReturn = ReturnType<typeof foo>; // number

しかし、ジェネリック関数の文脈で使うには問題があります。

function foo<T>(e: T): T {
    return e;
}

type fooReturn = ReturnType<typeof foo>; // type fooReturn = {}

type fooReturn = ReturnType<typeof foo<number>>; // syntax error

type fooReturn = ReturnType<(typeof foo)<number>>; // syntax error

汎用関数が特定の型のパラメータを与えたときの戻り値の型を抽出する方法はありますか?

どのように解決するのですか?

TypeScriptコンパイラが typeof foo を総称型と見なさない。コンパイラのバグとしか言いようがない。

しかし、TypeScriptでは 呼び出し可能なインターフェイス があり、問題なく汎用的に使えるので、関数のシグネチャと互換性のある呼び出し可能なインタフェースを導入すれば、それに相当するものを独自に実装することができます。 ReturnType をこのように実装することができます。

function foo<T>(x: T): T {
  return x;
}


interface Callable<R> {
  (...args: any[]): R;
}

type GenericReturnType<R, X> = X extends Callable<R> ? R : never;

type N = GenericReturnType<number, typeof foo>; // number