[英]How to define an array type with items of different types and with a specific order in TypeScript?
假设我想拥有一个数组,该数组的项目可以接受不同的类型,但还需要针对这些类型的特定顺序。
例如,假设MyArrayType
要求第一个项目必须是A
类型,最后一个项目必须是C
类型,而介于两者之间的所有项目都必须是B
类型。
const a: A = ....;
const b1: B = ....;
const b2: B = ....;
.
.
.
const bn: B = ....;
const c: C = ....;
const arr: MyArrayType = [a, b1, b2,...., bn, c]; //compiles
const arr2: MyArrayType = [c, b1, b2,...., bn, a]; //doesn't compile
可以定义这样的数组类型吗?
我想我明白了。 通过递归,我们可以在末尾创建C类型的元组,并在开始时创建B项对。
之后,按照建议@ titian-cernicova-dragomir,我们可以在元组的开头添加A类型。
不幸的是,此解决方案需要B项的准确计数。
码:
type A = 1;
type B = 2;
type C = 3;
type ZeroTuple = [];
type PrependTuple<A, T> = T extends Array<any>
? (((a: A, ...b: T) => void) extends (...a: infer I) => void ? I : [])
: [];
type TupleLength<T extends Array<any>> = T["length"];
type NumberToTuple<N extends number, L extends Array<any> = [C]> = {
true: L;
false: NumberToTuple<N, PrependTuple<B, L>>;
}[TupleLength<L> extends N ? "true" : "false"];
type MyArrayType = PrependTuple<A, NumberToTuple<4>>;
// or make it more generic
type MyArrayType<N extends number> = PrependTuple<A, NumberToTuple<N>>;
NumberToTuple将以递归方式将B元素附加到[C],然后是[B,C],[B,B,C]。
在N次元组[... b [],C]之后,我们必须在A项之前添加。
我同意评论者的意见。 这种数据结构很难处理。 除了已经建议的以外,我还可以推荐类似[A, B[], C]
:
type ABC = [A, B[], C];
const arr: ABC = [a, [b1, b2, ...bn], c]; //compiles
const arr2: ABC = [c, [b1, b2, ...bn], a]; // does not compile
语法几乎与您所要求的相同,但是我知道这可能还不够。 如果潜在b
的数量相对较少,您还可以执行以下操作:
type AB1C = [A, B, C];
type AB2C = [A, B, B, C];
type AB3C = [A, B, B, B, C];
type ABC = AB1C | AB2C | AB3C;
const arr: ABC = [a, b1, b2, bn, c]; //compiles
const arr2: ABC = [c, b1, b2, bn, a]; // does not compile
当然,它不是很优雅,但是请注意, length
属性用作区分符,因此以下内容完全有效:
function getC(abc: ABC): C {
switch (abc.length) {
case 3: return abc[2];
case 4: return abc[3];
case 5: return abc[4];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.