代码之家  ›  专栏  ›  技术社区  ›  Curtis

具有并集类型和元组的扩展运算符

  •  1
  • Curtis  · 技术社区  · 6 年前

    我有一把钥匙,可以是 number 或类型 [number] [number, number] ;

    union type

    type Foo    = [number, number?];
    type Bar    = number;
    type FooBar = Foo | Bar;
    

    然后我编写了一个比较方法来分析其中的两个键。

    我的问题是,我想限制比较,使两个参数必须是同一类型。比较 Foo Bar 酒吧 但不是

    如果我按照以下方法进行比较:

    compare(key1: FooBar, key2: FooBar)
    

    然后它将接受这种不匹配比较: compare([1], 1)

    如果我再定义一些类型:

    type FooFoo = [Foo, Foo];
    type BarBar = [Bar, Bar];
    

    并将比较签名更改为:

    compare(keys: FooFoo|BarBar)
    

    它会正确地将两个键限制为同一类型,但这意味着您必须将compare参数作为数组传递,这很难看。所以我决定尝试使用spread操作符 ...

    compare(...keys: FooFoo|BarBar)
    

    但它返回一个错误,指出foooo需要是一个数组。如果我使用 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 一切都安排好了。我希望我想做的是可能的。谢谢你的建议。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Curtis    6 年前

    这是 fixed

    对于旧版本的解决方案,可以使用TypeScript重载(多谢了。 使用TypeScript重载时的注意事项:您必须为每个重载创建一个签名,并创建一个将同时支持所有重载的通用签名。 See here

    推荐文章