Farad
Farad

Reputation: 1065

How to implement interface for tree

I have a tree structure TableOfContents:

export interface TableOfContents {
  id: number;
  title: string;
  isExpanded: boolean;
  children: TableOfContents[];
}

I need a function for searching an item in array of trees and want to make it generic. So I did the next:

export interface TreeNode {
  [key: string]: any;
  children?: TreeNode[];
}

export interface TableOfContents extends TreeNode {
  id: number;
  title: string;
  isExpanded: boolean;
}

export const findInTrees = <TreeType extends TreeNode>(
  trees: TreeType[],
  callback: (el: TreeType) => boolean
): TreeType | null => {
  const tree = trees.find(tree => callback(tree));
  if (tree) {
    return tree;
  }
  for (const tree of trees) {
    if (tree.children) {
      const result = findInTrees(tree.children, callback);
      if (result) {
        return result;
      }
    }
  }
  return null;
};

But have an error TS2345: Argument of type 'TreeNode[]' is not assignable to parameter of type 'TreeType[]'. on the line const result = findInTrees(tree.children, callback);

Could you please help me to find a solution?

Upvotes: 1

Views: 841

Answers (2)

izzaki
izzaki

Reputation: 258

export type INode<T = any> = T & {
    nodes: Array<INode<T>>;
}



const family: INode<{name?: string}> = {
    name: 'Bogdan',
    nodes: []
};

Upvotes: 0

Aplet123
Aplet123

Reputation: 35540

In your TreeNode interface, your code says that children should be an array of anything that implements TreeNode, when really what you mean is that children should be an array of the same type of TreeNode. So, use the this type:

export interface TreeNode {
  [key: string]: any;
  children?: this[];
}

Upvotes: 4

Related Questions