Typescript-在js中处理动态分组结果



我目前有一个返回JSON的端点,如下所示:

const tags = [
{
"name": "advertiser id",
"id": "12345",
"data_type": "output_type"
},
{
"name": "advertiser id",
"id": "345678",
"data_type": "output_type"
},
{
"name": "my name",
"id": "564563",
"data_type": "input_type"
},

]

假设这个JSON包含大量不同形式的数据类型。目前,有output_type **(2)**input_type **(1)**,但这可能是广泛的。因此,为了简化前端,我将其分组。

Lodash:const grouped = _.groupBy(tags, tag => tag.data_type);

在Lodash中,与上面的内容类似,这并不重要,但您需要知道的是,数据类型将成为一个密钥,我尝试键入的最终JSON看起来是这样的:

const tags = {
output_type: [{
"name": "advertiser id",
"id": "12345",
},
{
"name": "advertiser id",
"id": "345678",
}],

input_type: [
{
"name": "my name",
"id": "564563",
}],
}

以下是我如何在typescript中键入这个问题的示例:

export interface TagDefinition {
name: string;
id: string;
}
export interface GroupedTags {
output_type: TagDefinition[];
input_type: TagDefinition[];
}
export interface TagsState {
tags: Tags[];
groupedTags: GroupedTags;
error?: Error;
}

然而,我的问题是,考虑到端点可以在任何时候返回任何data_type,我在这里的类型是:

export interface GroupedTags {
output_type: TagDefinition[];
input_type: TagDefinition[];
}

在任何方面都不是动态的,并且依赖于我作为开发人员来定义每个键。我想知道Generic是否有什么神奇的方法可以让它更灵活,如果有,会是什么样子。

编辑我认为Dictionary<ToolDefinition[]>是答案,但不是100%确定。

给定数据的形状:

type Data = {
name: string;
id: string;
data_type: "input_type" | "output_type";
};

这应该会让你走上你的路:

type Grouped<T, K extends keyof T> = T[K] extends PropertyKey ? Record<T[K], T[]> : never; 
type GroupedResult = Grouped<Data, "data_type">;// -> { input_type: Data[]; output_type: Data[]; }

如果你想删除公共密钥,K从T:

type GroupedOmitKey<T, K extends keyof T> = T[K] extends PropertyKey ? Record<T[K], Pick<T, Exclude<keyof T, K>>[]> : never;
type GroupedOmitKeyResult = GroupedOmitKey<Data, "data_type">; // -> { input_type: Array<{ name: string; id: string; }>; output_type: Array<{ name: string; id: string; }>; }

我建议你应该选择Record<string, TagDefinition[]>,你可以很容易地转换输入数据,但使用data_type作为键,然后插入所需的字段。

最新更新