The purpose behind
type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
? Return
: never;
is to extract the return type of any function without discriminating based on parameter types. Any function signature passed in as Type
should be assignable to
(...args: never[]) => infer Return
.
This means that (...args: never[]) => infer Return
should encompass all function signatures as a top type for functions. For further insight, refer to Alternative for "any function" ((...args: any[]) => any) without using any.
Considering that the parameters of Type
are disregarded and no actual function call of type Type
is made, there are various ways to define a function top type in TypeScript for this purpose. Here are different options listed in descending order of preference:
(...args: never) => infer Return
(...args: any) => infer Return
(...args: any[]) => infer Return
(...args: never[]) => infer Return
Function types exhibit contravariance in their parameter types, meaning a function type should align with fewer parameter types to match a wider range of function types. Consequently, for a top type that encompasses all function types, a bottom type for the parameters (i.e., an intersection of all parameter types) is required.
The "never" type serves as TypeScript's bottom type, making
(...args: never) => infer Return
the ideal function top type for type safety.
Alternatively, you can utilize any
type for this purpose, such as
(...args: any) => infer Return
. The intentional unsafety of the
any
type makes it suitable for scenarios where type is inconsequential and errors need to be avoided.
Another option is to use
(...args: any[]) => infer Return
, as
any[]
can accommodate any array type.
Lastly, there's
(...args: never[]) => infer Return
. A type of
never[]
signifies "an unindexable array," covering nearly all array types but not the precise intersection of all array types. Although it aligns with most functions, it should behave distinctively when called. While TypeScript treats
(...args: never) => ?
and
(...args: never[]) => ?
as identical, there are intricacies and bugs related to these types, as indicated in
microsoft/TypeScript#48840.
However, given that the function is not invoked in this scenario, the distinction between never[]
and never
is mainly theoretical. For the purpose of GetReturnType
, never[]
is equally suitable as never
.