TypeScript深度嵌套数组的接口

3

我完全不了解TypeScript,虽然在其他方面有所进展,但在为具有“taskName”和“totalTaskHours”的深度嵌套对象创建接口方面感到困难。 数据如下:

[
    {
      "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;
}

有人能帮我快速解决这个问题吗?我还在学习中,但基础教程并没有涵盖深度嵌套对象。谢谢!


这是一个非常不幸的数据结构(那些只有一个属性名称不同的对象)。你有更改它的选项吗? - T.J. Crowder
很遗憾,我没有更改的选项。这是API调用的响应JSON对象。 - chris.burkhardt
1个回答

1
你非常接近了。由于你的外部数组是一个数组,你可以定义其元素的类型(如下所示TaskItemHolder):
interface TaskItem {
  taskName: string;
  totalTaskHours: string;
}

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

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

在游乐场上直播

话虽如此,上述内容可以允许在TaskItemHolder上具有多个属性,而不仅仅是一个。正如我在评论中提到的,如果你能改变结构,那就改变吧。拥有一个属性名称变化的对象并不是一个好主意(即使不使用静态类型,但特别是当你使用静态类型时)。


如果您要循环遍历该数据,由于其问题结构,您可能会使用Object.keys(...)[0]来获取一个属性的键(或Object.entries(...)[0]来获取键和值,或只是Object.values(...)[0]来获取值):
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);
  }
}

现场副本

如果持有者中可能有其他属性,您可以使用键/条目/值数组:

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);
    }
  }
}

现场副本


感谢您的快速回复。我也尝试了那种方法,但第二和第三项的键是“undefined”,而不是{taskName: string; totalTaskHours: string;}。 - chris.burkhardt
@technicacreativejp - 我不明白你的意思,你所说的“第二个和第三个项目”是什么?数据中每个持有者都只有一个项目数组,并且该数组中的条目不是“未定义”。 - T.J. Crowder
当我添加了[]时,我遇到了以下问题: 类型“({“20229622”:{taskName:string;totalTaskHours:string;} []; “20229623”?:undefined;“20229624”?:undefined;} | {“20229623”:{taskName:string;totalTaskHours:string;} []; “20229622”?:未定义;“20229624”?:未定义;} | {...;})[]”不能赋值给类型“ TaskBreakdownSummedByCategory []”。 属性“” 20229623“”与索引签名不兼容。 类型“未定义”无法分配给类型“ TaskItem []”。 - chris.burkhardt
@technicacreativejp - 对于你展示的数据结构,你不需要TaskBreakdownSummedByCategory,只需要答案中所示的内容即可。如果你需要TaskBreakdownSummedByCategory来做其他事情,请说明你需要它做什么以及如何使用它。 - T.J. Crowder
如何将两个接口合并? - Phaneendra Charyulu Kanduri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接