【问题标题】:Typescript interface for tree structure树结构的打字稿接口
【发布时间】:2020-08-23 03:50:53
【问题描述】:

我想为树形结构定义一个接口。

每个节点可以有零个或多个子节点:

export interface TreeNode {
  children?: Array<TreeNode>;
}

我已经为TreeNodes 实现了一个遍历函数。

export function traverseTree(treeData: Array<TreeNode> | TreeNode, callback: (treeNode: any) => any) {
  // implementation omitted
}

我想测试一下。代码如下:

const treeData = [
  {
    name: "root_1",
    children: [
      {
        name: "child_1",
        children: [
          {
            name: "grandchild_1"
          },
          {
            name: "grandchild_2"
          }
        ]
      }
    ]
  },
  {
    name: "root_2",
    children: []
  }
];
const traversingHistory = [];
const callback = (treeNode: any) => {
  traversingHistory.push(treeNode.name);
}
traverseTree(treeData, callback);

但是,编译失败,因为treeData 的类型参数不能应用于traverseTree

我不想将属性name 添加到接口TreeNode,因为树节点可以具有动态属性。如何修改TreeNode 接口以接受更通用的类型?

【问题讨论】:

    标签: javascript typescript interface tree


    【解决方案1】:

    您可能遇到的错误是:

    对象字面量只能指定已知属性,类型中不存在'name'

    如果你想允许其他键,它必须是类型的一部分。您可以使用索引签名来做到这一点:

    export interface TreeNode {
      [key: string]: any // type for unknown keys.
      children?: TreeNode[] // type for a known property.
    }
    

    【讨论】:

      【解决方案2】:

      我想使用generic 代替[key: string]: any 更合适:

      export type Tree<T> = T & {
        children?: T[];
      }
      

      保留我们要构建树的Item 类型的必填和可选字段:Tree&lt;Item&gt; 对于这个问题,Item 是:{ name: string }

      【讨论】:

        【解决方案3】:

        尝试将此联合类型与object 一起使用:

        type TreeNode = {
            children?: Array<TreeNode>;
        } & object;
        

        【讨论】:

        • Alex Wayne 的答案更好。但作为一种变体
        猜你喜欢
        • 2017-09-02
        • 1970-01-01
        • 2019-12-12
        • 2019-06-01
        • 2016-04-04
        • 1970-01-01
        • 2016-09-14
        • 2020-08-14
        • 2019-05-04
        相关资源
        最近更新 更多