There are two different types of functions: one that returns a string
and the other that returns a Promise<string>
. Now, I am looking to create a function that can wrap both types, but I need to be able to distinguish between them when invoking the fn
function.
type FuncTypes = (...args: any[]) => string | Promise<string>
function callFunc(fn: FuncTypes, ...args: any[]) {
// Need to differentiate if fn returns a string or a Promise<string>
// If fn returns a string
return new Promise<string>(r => r(fn.call(this, ...args)))
// If fn returns a Promise
return fn.call(this, ...args)
}
Another scenario is overloading:
type FuncA = (...args: any[]) => string
type FuncB = (...args: any[]) => Promise<string>
function callFunc(fn: FuncA, ...args: any[]): Promise<string>
function callFunc(fn: FuncB, ...args: any[]): Promise<string>
function callFunc(fn: any, ...args: any[]): Promise<string> {
// If fn is an instance of FuncA
// Do something
// Else if fn is an instance of FuncB
// Do something
}
While we can use
const returned = fn(..args); typeof returned === 'string'
to check the return type, this is not a universal solution. When the function type is () => AnInterface|AnotherInterface
, it becomes challenging to determine the return type using typeof
or instanceof
.
Is there a general approach to distinguishing these function types, or should I create separate functions for each type?