我有一个密钥,可以是number
类型,也可以是[number]
类型,也可以是[number, number]
类型;
我分别为每个类型和一个union type创建了一个类型,
type Foo = [number, number?];
type Bar = number;
type FooBar = Foo | Bar;
然后我写了一个比较方法,可以分析其中两个键。
我的问题是,我想限制比较,以便两个参数必须是同一类型。 IE比较Foo
和Foo
或Bar
和Bar
,但不比较Foo
和Bar
。
如果我按如下方法进行比较:
compare(key1: FooBar, key2: FooBar)
然后它将接受这种未命中的比较:compare([1], 1)
如果我这样定义更多类型:
type FooFoo = [Foo, Foo];
type BarBar = [Bar, Bar];
并将比较签名更改为:
compare(keys: FooFoo|BarBar)
它将正确地将两个键限制为相同类型,但这意味着您必须将compare参数作为数组传递,这很丑陋。因此,我决定尝试使用传播运算符...
compare(...keys: FooFoo|BarBar)
但是它返回一个错误,指出FooFoo需要是一个数组。如果我使用compare(...keys: FooFoo)
,它不会抱怨(但仅限于FooFoo
)。而且,如果我使用compare(...keys: BarBar)
,它也不会抱怨(但仅限于BarBar
)。
有什么方法可以正确重载此方法,使其等同于:
//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
我已经设置好所有内容的stackblitz example。我希望我能做的是可能的。感谢您的任何建议。