So, I've the below ts
file, where I'm trying to add the type annotation GetTokenResponse
to a function getToken
.
import { ConfigService } from '@nestjs/config';
import { google, GoogleApis } from 'googleapis';
import { AppConfig } from 'src/configurations/app.config';
type OAuth2Client = InstanceType<GoogleApis['auth']['OAuth2']>;
type GetTokenResponse = ReturnType<OAuth2Client['getToken']>;
getToken(code: string): GetTokenResponse {
return this.oAuth2Client.getToken(code);
}
The below block of code (already mentioned in above snippet) returns void
type GetTokenResponse = ReturnType<OAuth2Client['getToken']>; //void
because
the function getToken
has 3 overloads:
getToken(code: string): Promise<GetTokenResponse>;
getToken(options: GetTokenOptions): Promise<GetTokenResponse>;
getToken(code: string, callback: GetTokenCallback): void;
getToken(options: GetTokenOptions, callback: GetTokenCallback): void;
So, how do I extract the type Promise<GetTokenResponse>
from the getToken
function?
@see https://github.com/sindresorhus/type-fest/issues/585
https://tsplay.dev/Nll5xN
type GetTokenResponse = { GetTokenResponse: true }
type GetTokenCallback = { GetTokenCallback: true }
type GetTokenOptions = { GetTokenOptions: true }
type x = {
getToken(code: string): Promise<GetTokenResponse>;
getToken(options: GetTokenOptions): Promise<GetTokenResponse>;
getToken(code: string, callback: GetTokenCallback): void;
getToken(options: GetTokenOptions, callback: GetTokenCallback): void;
}
// support 5 times overload at most
type OverloadedReturnType<T> =
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R; (...args: any[]) : infer R ; (...args: any[]) : infer R; (...args: any[]) : infer R } ? R :
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R; (...args: any[]) : infer R ; (...args: any[]) : infer R } ? R :
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R; (...args: any[]) : infer R } ? R :
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R } ? R :
T extends (...args: any[]) => infer R ? R : any;
type R = OverloadedReturnType<x['getToken']>
// ^?
// type R = void | Promise<GetTokenResponse>