I'm defining from
function that can take 1 or 2 arguments; it returns a lambda that takes the same number of arguments.
I thought the return type of this function could be a conditional type verifying if the second argument is set, and returning a lambda with 1 or 2 arguments as appropriate:
type Consumer1<V1> = (a1: V1) => void
type Consumer2<V1, V2> = (a1: V1, a2: V2) => void
class Wrapper<V> {
unwrap(a: V) {}
}
function from<V1, V2>(a1: Wrapper<V1>, a2?: Wrapper<V2>):
typeof a2 extends undefined ? Consumer1<V1> : Consumer2<V1, V2>
{
if (typeof a2 === 'undefined') {
return (a1: V1) => {}
}
return (a1: V1, a2: V2) => {}
}
from(new Wrapper<number>())(1)
// expected 2 arguments, but got one
As one can see on the last line of the block above, from
always returns a Consumer2
. Any idea as of why? I thought that since a2
is not set, typeof a2
would be undefined and from
would return a Consumer<number>
.
Thanks, JM
The most straightforward solution is probably to use function overloads:
type Consumer1<V1> = (a1: V1) => void
type Consumer2<V1, V2> = (a1: V1, a2: V2) => void
class Wrapper<V> {
unwrap(a: V) {}
}
function from<V1>(a1: Wrapper<V1>): Consumer1<V1>;
function from<V1, V2>(a1: Wrapper<V1>, a2: Wrapper<V2>): Consumer2<V1, V2>;
function from<V1, V2>(a1: Wrapper<V1>, a2?: Wrapper<V2>):
Consumer1<V1> | Consumer2<V1, V2> {
if (typeof a2 === 'undefined') {
return (a1: V1) => {}
}
return (a1: V1, a2: V2) => {}
}
from(new Wrapper<number>())(1);