好的,所以这主要是出于我的好奇心。见下面的代码:
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.
答案 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
}
也适用于一到七个元素,可以扩展。
所以这些都是适合你的想法。希望他们帮忙。祝你好运!