I am trying to get function overloads working with a function that takes a generic type param.
Originally I have a function foo
interface Props<T, S> {
fn?: (response: S) => T[];
enable?: boolean;
}
type Result = {
irrelevant?: any;
};
function foo<T, S>(props: Props<T, S>): Result {
}
I omit the implementation details of this function because it is not relevant to this question.
Now I want this function to return two different types according to whether enable in Props is true or false / undefined
The idea is that, if the param the user gives to the function has enable: true in it, then the returned value from foo should have a property called update, and the user can safely descructure that from the returned value.
My attempt for that is to use function overload,
export interface Updater {
updater: () => void;
}
export type Result = {
irrelevant?: any;
};
export type CombinedResult = Result & Updater;
export function foo<T, S, U extends Props<T, S>>(
props: U
): U extends { enable: true } ? CombinedResult : Result;
export function foo<T, S>(props: Props<T, S>): CombinedResult | Result {
if (props.enable === true) {
return {
updater: () => {
console.log("updater!");
}
};
}
return {};
}
Now the problem is, with this function overload, foo will ask for a third generic argument U in addition to T and S. So I will have this error
Expected 3 type arguments, but got 2.ts(2558)
const { updater } = foo<string, string[]>({ // 🚨 Expected 3 type arguments, but got 2.ts(2558)
fn: (strings) => strings,
enable: true
});
Here is a live demo you can play with https://codesandbox.io/s/overload-with-generics-gbsok?file=/src/index.ts
Also please feel free to suggestion any other approach that you think can achieve the goal here