Typescript 通用接口数组
Typescript Generic Array of Interfaces
我对 TypeScript 中更高级的泛型类型有疑问。
我想要做的是一个数据数组,其中 data
本身由 type
控制,例如:
[
{
type: "T1",
content: number,
},
{
type: "T2",
values: {
id: number,
...
}
}
]
在描述了可用的类型后,我有点不知所措:
enum DataType {
T1 = "t1",
T2 = "t2"
}
所以我猜结果一定是这样的:
interface DataGeneric<T> {
[T extends DataType.T1]: { content: number },
[T extends DataType.T2]: { values: { id: number, ... } },
} ???
interface Data<T extends DataType = any(?)> extends DataGeneric<T>{
type: DataType,
// and all the other fields are generic from T = DataType
}
const someData: Data[] | undefined = fetchData();
// suggesting that the `type` of element[1] is "t2"
// and VSCode suggestions works correctly too,
// consider that there is an object-field `values` with `id` key
someData[1].values.id
提前致谢!
如果您要根据字符串或数字 literal to discriminate what type of data the rest of the object is holding, then you probably want to use a discriminated union instead of generics. That's basically a union type 检查对象的 type
属性,其中联合成员具有共同的 判别式 键。在您的情况下,它可能看起来像这样:
enum DataType {
T1 = "t1",
T2 = "t2"
}
type Data =
{ type: DataType.T1, content: number } |
{ type: DataType.T2, values: { id: number } }
然后当你有一个 data
类型 Data
的值时,你可以检查它的 type
属性 并且编译器知道它应该缩小 data
到工会的右成员:
declare const someData: Data[] | undefined;
if (someData) {
someData.forEach(data => {
if (data.type === DataType.T1) {
data.content.toFixed();
} else {
data.values.id.toFixed();
}
})
}
我对 TypeScript 中更高级的泛型类型有疑问。
我想要做的是一个数据数组,其中 data
本身由 type
控制,例如:
[
{
type: "T1",
content: number,
},
{
type: "T2",
values: {
id: number,
...
}
}
]
在描述了可用的类型后,我有点不知所措:
enum DataType {
T1 = "t1",
T2 = "t2"
}
所以我猜结果一定是这样的:
interface DataGeneric<T> {
[T extends DataType.T1]: { content: number },
[T extends DataType.T2]: { values: { id: number, ... } },
} ???
interface Data<T extends DataType = any(?)> extends DataGeneric<T>{
type: DataType,
// and all the other fields are generic from T = DataType
}
const someData: Data[] | undefined = fetchData();
// suggesting that the `type` of element[1] is "t2"
// and VSCode suggestions works correctly too,
// consider that there is an object-field `values` with `id` key
someData[1].values.id
提前致谢!
如果您要根据字符串或数字 literal to discriminate what type of data the rest of the object is holding, then you probably want to use a discriminated union instead of generics. That's basically a union type 检查对象的 type
属性,其中联合成员具有共同的 判别式 键。在您的情况下,它可能看起来像这样:
enum DataType {
T1 = "t1",
T2 = "t2"
}
type Data =
{ type: DataType.T1, content: number } |
{ type: DataType.T2, values: { id: number } }
然后当你有一个 data
类型 Data
的值时,你可以检查它的 type
属性 并且编译器知道它应该缩小 data
到工会的右成员:
declare const someData: Data[] | undefined;
if (someData) {
someData.forEach(data => {
if (data.type === DataType.T1) {
data.content.toFixed();
} else {
data.values.id.toFixed();
}
})
}