有没有办法在不使用数组文字类型表示法的情况下声明元组?

时间:2018-06-06 16:31:30

标签: typescript

好的,所以这主要是出于我的好奇心。见下面的代码:

const a: [string, number] = ["string", 1]; //valid
const b: Array<string, number> = ["string", 1]; //invalid
const c: Array<[string, number]> = ["string", 1] //invalid, it means [["string", 1]]

除非使用[]表示法,否则似乎无法声明元组。我的下一个想法是寻找一个元组类型,但似乎没有任何内置。

您可以像Tuple那样声明type Tuple<K, V> = [K, V]类型,但这会破坏整个想法。

还有类似的东西:

let d: Array<string | number> = ["string", 1]

会编译,但您可以为其分配["string", "another string", 1, 2, "stuff"]之类的内容。

更新1: 正如@jcalz type Tuple<K, V> = [K, V]所示,它不正确,因为它将元组类型的元素数限制为2.

1 个答案:

答案 0 :(得分:3)

究竟是什么&#34;击败了整个想法&#34; type Tuple<K, V>的?是Tuple<>不允许任意数量的类型参数吗?或者它在其定义中使用[]

根据您的使用情况,以下是解决方案的一种可能途径:

type Tuple<A, B = never, C = never, D = never, E = never, F = never, G = never> =
  [G] extends [never] ? [F] extends [never] ? [E] extends [never] ?
  [D] extends [never] ? [C] extends [never] ? [B] extends [never] ?
  [A] : [A, B] : [A, B, C] : [A, B, C, D] : [A, B, C, D, E] :
  [A, B, C, D, E, F] : [A, B, C, D, E, F, G]

此处Tuple<>conditional type,使用default generic parameters允许您指定一到七个元组元素之间的任何位置:

const e: Tuple<string, number> = ["string", 1]; // okay

如果你需要更多的元素,你可以扩展上面的定义,尽管如果没有类似variadic kinds的东西,你永远不会得到任意数量的元素,这些不是TypeScript的一部分(无论如何都是2.9)。

或许这不算数,因为在定义中使用了元组语法。如果你想完全避免使用元组语法,你可以尝试创建一个类似于元组的类型......对于这两个元素的情况就是这样的:

interface FakeTuple2<A, B> extends Array<A | B> {
  readonly length: 2,
  0: A,
  1: B,
}

根据您的需要,这可以用于多种目的:

const f: FakeTuple2<string, number> = ["string", 1]; // okay

如果你想要一个可变数量的元素以及假元组,你可以使用上述两种方法得到类似的东西:

type StripNever<T> = Pick<T, { [K in keyof T]: T[K] extends never ? never : K }[keyof T]>
type FakeTuple<A, B = never, C = never, D = never, E = never, F = never, G = never> =
  Array<A | B | C | D | E | F | G> & 
  StripNever<{ 0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G }> & {
    length: [G] extends [never] ? [F] extends [never] ? [E] extends [never] ?
    [D] extends [never] ? [C] extends [never] ? [B] extends [never] ? 
    1 : 2 : 3 : 4 : 5 : 6 : 7
  }

也适用于一到七个元素,可以扩展。

所以这些都是适合你的想法。希望他们帮忙。祝你好运!