I have a key that can either be of type number
or type [number]
or type [number, number]
;
I created a type for each and a union type that can be either:
type Foo = [number, number?];
type Bar = number;
type FooBar = Foo | Bar;
I then wrote a compare method that would analyze two of these keys.
My issue is, I want to limit the compare so that the two parameters must be of the same type. IE compare of Foo
and Foo
or Bar
and Bar
but not Foo
and Bar
.
If I make the compare method as follows:
compare(key1: FooBar, key2: FooBar)
then it will accept this kind of miss matched compare: compare([1], 1)
If I define some more types as such:
type FooFoo = [Foo, Foo];
type BarBar = [Bar, Bar];
and change the compare signature to:
compare(keys: FooFoo|BarBar)
It will correctly limit the two keys to be the same type but that means that you have to pass the compare parameter as an array, which is ugly. So I decided to try and use the spread operator ...
compare(...keys: FooFoo|BarBar)
But it returns an error saying that FooFoo needs to be an array. If I use compare(...keys: FooFoo)
it doesn't complain (but is limited to only FooFoo
). And if I use compare(...keys: BarBar)
it also doesn't complain (but is limited to only BarBar
).
Is there any way to correctly overload this method to be equivalent to:
//an example of what I want.
//Using Java or C#'s overloading style for illustration
function compare(k1: Bar, k2: Bar): boolean {
return compare([key1], [key2]);
}
function compare(k1: Foo, k2: Foo): boolean {
if (k1 === k2) { return true; }
if (Array.isArray(k1) && Array.isArray(k2)) {
return k1[0] === k2[0] && (k1[1] === k2[1] ||
(!isSet(k1[1]) && !isSet(k2[1])));
}
return false;
}
//this would result in allowing and not allowing the following:
compare(1, 2); //valid
compare([1], [2]); //valid
compare([1, 2], [3, 4]); //valid
compare([1, 2], [3]); //valid
compare([1], [2, 3]); //valid
compare([1], 2); //not valid
compare([1, 2], 3); //not valid
compare(1, [2]); //not valid
compare(1, [2, 3]); //not valid
I've set up a stackblitz example with everything laid out. I hope what I am trying to do is possible. Thanks for any suggestions.