Typescript二维可变模板

Typescript二维可变模板,typescript,templates,generics,variadic,Typescript,Templates,Generics,Variadic,我目前有一个接口,它使用其他接口类型的数组的数据成员,可以通过枚举来确定: enum E{a,b,c} 接口数据{ [E.a]:{a:string}, [E.b]:{b:string}, [E.c]:{c:string} } 接口A{ 数据:{[i in keyof T]:T[i]扩展了E?E2Data[T[i]]:never} } //可以在模板中提供枚举,并在数据中获得自动完成。 设a1:A={ 数据:[{a::},{b::}] }; //或者可以通过元素上的类型断言获得自动完成。 //理想

我目前有一个接口,它使用其他接口类型的数组的数据成员,可以通过枚举来确定:

enum E{a,b,c}
接口数据{
[E.a]:{a:string},
[E.b]:{b:string},
[E.c]:{c:string}
}
接口A{
数据:{[i in keyof T]:T[i]扩展了E?E2Data[T[i]]:never}
}
//可以在模板中提供枚举,并在数据中获得自动完成。
设a1:A={
数据:[{a::},{b::}]
};
//或者可以通过元素上的类型断言获得自动完成。
//理想情况下,这也可以推断模板类型,但显然不是。
设a2:A={
数据:[{a::},{b::}]
}
根据我的理解,我现在可以使用
a1.data
a2.data
作为数组,但是
a1.data
知道每个元素的类型(实际上是元组?)

现在我想为
接口a
的数据使用2D数组

我原以为下面的方法行得通,但它不允许我使用
T[I][j]
索引
E2Data

接口B{
数据:{
[i在keyof T中]:
T[i]扩展了E[]{
[j in keyof T[i]]:
T[i][j]扩展了E?E2Data[T[i][j]]:never}
//                      ^^^^^^^^^^^^^^^
//类型“T[i][j]”不能用于索引类型“E2Data”。
:从不
}
}
我当前的解决方法是使用类型联合,但这不允许我使用模板指定所需的数据

接口B{
数据:(E2Data[E.a]| E2Data[E.b]| E2Data[E.c])[];
}
对于2D阵列,是否有一种方法可以支持上述两种在
数据上自动完成的方法

让b1:A={
数据:[{a::}],{b::}]]
}
设b2:A={
数据:[{a::}],{b::}]]
}

这让我思考了一下,但解决方案实际上非常简单,因为您已经用原始的
接口A
完成了大部分工作

定义一个泛型类型
DataArray
,它将一个E值元组作为泛型,并返回一个对应的E2Data元组。您可以重新格式化,使
DataArray
包含逻辑,而
A
使用它,但为了简单起见,让我们只从
A
访问现有逻辑

type DataArray<T extends E[]> = A<T>['data'];
现在,您可以通过混合和匹配E来创建任何2D数据类型

let b: B<[[E.a], [E.b, E.c]]> = {
    data: [ [{ a: "" }], [{ b: "" }, {c: ""}] ]
}
让b:b={
数据:[{a::}],{b::},{c::}]]
}
编辑 我知道您没有要求这样做,但下面是如何处理更深层嵌套的值。(有一些关于递归数组的指导)

接口嵌套扩展数组{
}
类型NestedData={
[i in keyof T]:T[i]扩展E?E2数据[T[i]:T[i]扩展嵌套?嵌套数据:从不
}
接口C{
数据:嵌套数据
}
设c:c={
数据:[{a:”“},[{b:”“},[{c:”“}]]
}

B.data中的单个数组是否包含不同数据类型的组合,或者它们是按类型分组的?例如,如果您只需要一个E.a数据数组和一个E.b数据数组,那么这很容易。您所需要做的就是在接口A中将
E2Data[T[i]]
替换为
E2Data[T[i]][
。但我怀疑您需要混合类型,否则您不会发布此内容。所需的数据类型类似于解决方法
接口B
。你下面的答案涵盖了这一点!
let b: B<[[E.a], [E.b, E.c]]> = {
    data: [ [{ a: "" }], [{ b: "" }, {c: ""}] ]
}
interface Nested<T> extends Array<Nested<T> | T> {
}

type NestedData<T extends Nested<E>> = { 
    [i in keyof T]: T[i] extends E ? E2Data[T[i]] : T[i] extends Nested<E> ? NestedData<T[i]> : never
}

interface C<T extends Nested<E>> {
    data: NestedData<T>
}

let c: C<[E.a, [E.b, [E.c]]]> = {
    data: [ { a: "" }, [{ b: "" }, [{c: ""}] ]]
}