【问题标题】:TypeScript Interface for deeply nested array用于深度嵌套数组的 TypeScript 接口
【发布时间】:2019-03-18 14:00:17
【问题描述】:

我对 Typescript 完全陌生,并且已经能够在其他领域取得一些进展,但我正在努力为具有“taskName”和“totalTask​​Hours”的深度嵌套对象创建接口。数据如下所示:

[
    {
      "20229622": [
        {
          "taskName": "Project Management",
          "totalTaskHours": "1589.4"
        },
        {
          "taskName": "Marketing",
          "totalTaskHours": "1306.8"
        },
        {
          "taskName": "Design",
          "totalTaskHours": "212.4"
        },
        {
          "taskName": "Programming",
          "totalTaskHours": "415.8"
        }
      ]
    },
    {
      "20229623": [
        {
          "taskName": "Project Management",
          "totalTaskHours": "980.1"
        },
        {
          "taskName": "Marketing",
          "totalTaskHours": "717.3"
        },
        {
          "taskName": "Design",
          "totalTaskHours": "468.9"
        }
      ]
    },
    {
      "20229624": [
        {
          "taskName": "Programming",
          "totalTaskHours": "5930.1"
        },
        {
          "taskName": "Project Management",
          "totalTaskHours": "997.2"
        },
        {
          "taskName": "Marketing",
          "totalTaskHours": "2108.69"
        },
        {
          "taskName": "Design",
          "totalTaskHours": "529.2"
        }
      ]
    }
  ]

我试图深入了解嵌套数组中的对象,但每次都会出错。

missing_other_nested_objects

我尝试过以下方法(显然是错误的):

interface TaskItem {
  taskName: string;
  totalTaskHours: string;
}

interface TaskItemArray {
  [key:string]: {
    [key:string]: TaskItem[];
  };
}
interface TaskBreakdownSummedByCategory {
  [key:string]: TaskItemArray[];
}

我也试过以下,但数据太浅了:

interface TaskItem {
  taskName: string;
  totalTaskHours: string;
}
interface TaskBreakdownSummedByCategory {
  [key:string]: TaskItem;
}

有人能很快帮我解决这个问题吗?我仍在学习,但基本教程并没有真正深入嵌套对象。谢谢!

【问题讨论】:

  • 这是一个非常不幸的数据结构(那些具有不同属性名称的对象)。您可以选择更改它吗?
  • 很遗憾,我没有更改选项。它是来自 API 调用的响应 JSON 对象。

标签: typescript


【解决方案1】:

真的很亲密。由于您的外部数组是一个数组,您只需定义其元素的类型(下面的TaskItemHolder):

interface TaskItem {
  taskName: string;
  totalTaskHours: string;
}

interface TaskItemHolder {
  [key: string]: TaskItem[];
}

那么整个数组的类型是TaskItemHolder[]

Live on the playground

也就是说,上面将允许TaskItemHolder 上的多个属性,而不仅仅是一个。正如我在评论中提到的,如果你可以改变结构,我会的。拥有一个具有一个名称不同的属性的对象不是一个好主意(即使不使用静态类型也不行,但尤其是当你使用静态类型时)。


如果您要遍历该数据,由于结构存在问题,您可能会使用Object.keys(...)[0] 来获取一个属性的键(或Object.entries(...)[0] 来获取键和值,或者只使用@ 987654330@获取值):

for (const holder of data) {
  const key = Object.keys(holder)[0];
  console.log("Holder with key " + key + ":");
  for (const entry of holder[key]) {
    console.log(entry.taskName);
  }
}

Live copy

或者如果持有者中可以有其他属性,则只使用该键/条目/值数组:

for (const holder of data) {
  for (const [key, value] of Object.entries(holder)) {
    console.log("Holder with key " + key + ":");
    for (const entry of value) {
      console.log(entry.taskName);
    }
  }
}

Live copy

【讨论】:

  • 感谢您的快速回复。我也尝试过这种方法,但是第二项和第三项的键是“未定义”而不是 {taskName: string;总任务时间:字符串;}。
  • @technicacreativejp - 我不关注你,你所说的“第二和第三项”是什么意思?数据中每个持有者恰好有 一个 项数组,并且该数组中的条目不是 undefined
  • 我在添加 [] 时得到了这个:Type '({ "20229622": { taskName: string; totalTask​​Hours: string; }[]; "20229623"?: undefined; "20229624"? : undefined; } | { "20229623": { taskName: string; totalTask​​Hours: string; }[]; "20229622"?: undefined; "20229624"?: undefined; } | { ...; })[]' 是不可分配给类型“TaskBreakdownSummedByCategory[]”。属性“20229623”与索引签名不兼容。类型“未定义”不可分配给类型“TaskItem[]”。
  • @technicacreativejp - 您不需要TaskBreakdownSummedByCategory(即,对于您显示的数据结构),只需答案中显示的内容即可。如果您需要TaskBreakdownSummedByCategory 用于其他用途,请说明您需要它的用途以及它的使用方式。
  • 两个界面如何结合?
猜你喜欢
  • 1970-01-01
  • 2021-03-30
  • 2019-04-17
  • 2017-03-28
  • 2023-03-14
  • 2020-12-10
  • 2020-12-30
  • 1970-01-01
  • 2019-05-05
相关资源
最近更新 更多