I have a function that can return one of 2 different types. I want to specify the return type using a generic parameter, but I don't want to specify the actual return type. Instead, I want to specify true
or false
and have the function map that to the actual return type. Is this possible in TypeScript?
// function that gets some data that can be parsed as a string[] or as a number
const getData = () => {
return JSON.parse('...');
};
// function that parses the data as a string[]
const fooTrue = () => {
return getData() as string[];
};
// function that parses the data as a number
const fooFalse = () => {
return getData() as number;
};
// the types for x and y work out, but I had to make 2 functions for foo (fooTrue and fooFalse)
const x = fooTrue(); // string[]
const y = fooFalse(); // number
// single function for foo
const foo = (flag: boolean) => {
if(flag) {
return getData() as string[];
}
return getData() as number;
}
// the types for xx and yy don't work out :(
const xx = foo(true); // number | string[]
const yy = foo(false); // number | string[]
// generic version, but you have to specify the actual return type
const fooGeneric = <T extends unknown>() => {
return getData() as T;
}
// the types for xxx and yyy work out, but I had to specify string[] and number instead of true/false
const xxx = fooGeneric<string[]>(); // string[]
const yyy = fooGeneric<number>(); // number
// function that converts true/false types to string[]/number types, respectively
const functionIWant = <???>(???) => {
???
}
const xxxx = functionIWant<true>(); // should return a string[]
const yyyy = functionIWant<false>(); // should return a number
CodePudding user response:
Typescript supports function overloading. So something like this is possible:
function foo(flag: true): string[];
function foo(flag: false): number;
function foo(flag: boolean) {
if(flag) {
return getData() as string[];
}
return getData() as number;
}
Note: Arrow functions cannot be overloaded
CodePudding user response:
A simple conditional type should work for you.
const functionIWant = <T extends boolean>(): T extends true ? string[] : number => {};