Problem
How can I expose an overloading implementation signature correctly?
Example
Building off of this question:
interface MyMap<T> {
[id: string]: T;
}
type Options = {
asObject?: boolean,
other?: Function
testing?: number
};
function get(options: { asObject: true, other?: Function, testing?:number }): MyMap<any>;
function get(options: { asObject?: false, other?: Function, testing?:number }): number[];
function get(): any[];
function get(options: Options = { asObject: false }): any[] | MyMap<any> {
if (options?.asObject) return {} as MyMap<any>;
return [];
}
How can I wrap this function but retain the possible return types depending on the options argument?
For example:
function wrapFunction(arg1 arg2, options) {
// do something with arg1 and arg2
return get(options)
}
Depending on the value set for options in the wrapFunction method, the return type would be based on the return type of get with that same value.
ie:
const g = wrapFunction(1,2, {asObject: true})
// Should return the same thing as get({asObject:true})
Attempted Solutions
I could simply rewrite a new signature for the wrapFunction, but this would be quite verbose, especially if I have many types of wrapFunctions that follow the same pattern of having a nested get call.
One suggestion was to type cast the wrapFunction as typeof get but this removes the ability to modify the parameters list of wrapFunction.
This might be related.