i want to define an overloaded function like
function first(n?: number) {
if (number === undefined) {
// returns a single Item
return items[0];
}
// returns an array of Item
return items.slice(0, n);
}
so that these statements type check:
const item: Item = first(); // no args, so return type is Item
const items: Array<Item> = first(5); // number arg, so return type is Array<Item>
flow knows that the first call to first
is going to result in n === undefined
(since it would complain if undefined
wasn't valid for n
) and it understands that it will then take the if branch, so i would think it could infer the return type is Item
, but everything i've tried either lets anything pass or always fails.
any idea if this is possible? thanks in advance internet.
I don't have a complete solution for you, but I got partway there:
const items = [1, 2, 3];
type FirstType = ((_: void) => number) & ((n: number) => Array<number>);
const first: FirstType = (n?: number) => {
if (n === undefined) {
// returns a single Item
return (items[0]: any);
} else {
// returns an array of Item
return (items.slice(0, n): any);
}
}
const a: number = first();
const b: Array<number> = first(2);
(tryflow)
The &
is an intersection type, and it means that first
must satisfy both of those types. You can see that the calls to first()
typecheck the way you want.
Unfortunately, it does not seem like Flow is currently able to typecheck the body of first
. Note that I had to cast the return values through any
to escape the typechecker. If you are willing to forgo typechecking in the body of your function, you can at least get it where the functions are called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With