I have the following function:
const lists = {mylist: ["alpha", "beta", "gamme"]};
function foo(listName, element) {
if (typeof element !== 'undefined') {
return !!lists[listName].find(x => x === element);
}
return [lists[listName], () => refreshLists()];
}
foo('mylist'); // returns [string[], () => any]
foo('mylist', 'alpha') // returns boolean
As you can see the function has 2 different return types depending if argument element
is set. How can I represent that properly with typescript, so that the editor chooses correct return type depending on how much arguments were passed?
My current solution looks like this but is not recognized by the editor:
export type FnReturnType<T> = [T] extends [undefined] ? [string[], () => any] : boolean;
function foo<T extends string | undefined>(listName: string, element: T): FnReturnType<T> {
if (typeof element !== 'undefined') {
return !!lists[listName].find(x => x === element);
}
return [lists[listName], () => refreshLists()];
}
How can I make a conditional type that return boolean if typeof element !== undefined
but otherwise [string[], () => any]
?
Use function overloading.
You write two separate overload signatures for a different argument types and return types and then you write function implementation that will return a correct value.
function foo(listName: string): [string[], () => any]; // overload signature #1
function foo(listName: string, element: string): boolean; // overload signature #2
function foo(listName: string, element?: string): boolean | [string[], () => any] { // function implementation
if (typeof element !== 'undefined') {
return !!lists[listName].find(x => x === element);
}
return [lists[listName], () => refreshLists()];
}
Check playground