Reputation: 1065
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
Reputation: 258
export type INode<T = any> = T & {
nodes: Array<INode<T>>;
}
const family: INode<{name?: string}> = {
name: 'Bogdan',
nodes: []
};
Upvotes: 0
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