admin管理员组

文章数量:1188236

I want to define an interface for tree structure.

Each node can have zero or more children:

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

I have implemented a traversing function for TreeNodes.

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

I want to test it. Code is as follows:

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

However, compilation fails because treeData's argument of type cannot be applied to traverseTree.

I don't want to add attribute name to interface TreeNode because a tree node can have dynamic properties. How can I modify TreeNode interface to accept more general types?

I want to define an interface for tree structure.

Each node can have zero or more children:

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

I have implemented a traversing function for TreeNodes.

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

I want to test it. Code is as follows:

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

However, compilation fails because treeData's argument of type cannot be applied to traverseTree.

I don't want to add attribute name to interface TreeNode because a tree node can have dynamic properties. How can I modify TreeNode interface to accept more general types?

Share Improve this question asked May 7, 2020 at 18:08 glinda93glinda93 8,4596 gold badges50 silver badges85 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 14

The error you are probably getting is:

Object literal may only specify known properties, and 'name' does not exist in type

If you want to allow other keys, it's got to be part of the type. You can do this with an index signature:

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

I guess that using a generic instead [key: string]: any fits better:

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

keeping the required and optional fields of the Item type we want to build a tree: Tree<Item> for this question, the Item is: { name: string }.

Try using this union type with object:

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

本文标签: javascriptTypescript interface for tree structureStack Overflow