【发布时间】:2020-09-25 11:04:44
【问题描述】:
我目前有一个接口使用其他接口类型的数组的数据成员,可以通过枚举确定:
enum E { a, b, c }
interface E2Data {
[E.a]: { a: string },
[E.b]: { b: string },
[E.c]: { c: string }
}
interface A<T extends E[] = E[]> {
data: { [i in keyof T]: T[i] extends E ? E2Data[T[i]] : never }
}
// Can give the enums in the template, and get autocomplete in the data.
let a1: A<[E.a, E.b]> = {
data: [{ a: "" }, { b: "" }]
};
// Or can get autocomplete with type assertion on elements.
// Ideally this would infer template types too, but apparently not.
let a2: A = {
data: [ <E2Data[E.a]>{ a: "" }, <E2Data[E.b]>{ b: "" } ]
}
根据我的理解,我现在可以使用a1.data 和a2.data 作为数组,但是a1.data 知道每个元素的类型(所以实际上是一个元组?)
现在我想为interface A 的数据使用二维数组。
我认为下面的方法可行,但它不允许我使用 T[i][j] 索引 E2Data。
interface B<T extends E[][] = E[][]> {
data: {
[i in keyof T]:
T[i] extends E[] ? {
[j in keyof T[i]]:
T[i][j] extends E ? E2Data[T[i][j]] : never }
// ^^^^^^^^^^^^^^^
// Type 'T[i][j]' cannot be used to index type 'E2Data'.
: never
}
}
我目前的解决方法是使用类型联合,但这不会让我使用模板指定我想要的数据。
interface B {
data: (E2Data[E.a] | E2Data[E.b] | E2Data[E.c])[][];
}
有没有办法支持data 上的 2 种自动完成方法,如上文所述的二维数组?
let b1: A<[ [E.a], [E.b] ]> = {
data: [ [{ a: "" }], [{ b: "" }] ]
}
let b2: A = {
data: [ [<E2Data[E.a]>{ a: "" }], [ <E2Data[E.b]>{ b: "" }] ]
}
【问题讨论】:
-
B.data 中的各个数组是否包含不同数据类型的组合,还是按类型分组?例如,如果您只想要一个 E.a 数据数组和一个 E.b 数据数组,那么这很容易。您需要做的就是将接口 A 中的
E2Data[T[i]]替换为E2Data[T[i]][]。但我怀疑您需要混合类型,否则您不会发布此内容。 -
所需的数据类型与解决方法
interface B中的一样。无论如何,您的回答都涵盖了这一点!
标签: typescript templates generics variadic