From 66111b9afa8546103d4cbf0b597c77c889d0a7cd Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Tue, 16 Jun 2020 14:21:28 +0300 Subject: [PATCH] feat: improve tree util types --- .../packages/core/src/lib/utils/tree-utils.ts | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts index 86844a4375..607a30ec52 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/tree-utils.ts @@ -1,20 +1,24 @@ -export class TreeNode { +export class TreeNodeFactory { children: TreeNode[] = []; isLeaf = true; constructor(props: T) { Object.assign(this, props); } + + static create(props: T) { + return new TreeNodeFactory(props) as TreeNode; + } } -export function createTreeFromList>( +export function createTreeFromList( list: T[], - keySelector: (item: T) => NodeKey, - parentKeySelector: (item: T) => NodeKey, - valueMapper = (item: T) => new TreeNode(item) as R, + keySelector: (item: T) => number | string | Symbol, + parentKeySelector: typeof keySelector, + valueMapper: (item: T) => R, ) { const map = createMapFromList(list, keySelector, valueMapper); - const tree: ReturnType[] = []; + const tree: NodeValue[] = []; list.forEach(row => { const id = keySelector(row); @@ -23,8 +27,8 @@ export function createTreeFromList>( if (parentId) { const parent = map.get(parentId); - parent.children.push(node); - parent.isLeaf = false; + (parent as any).children.push(node); + (parent as any).isLeaf = false; } else { tree.push(node); } @@ -33,19 +37,25 @@ export function createTreeFromList>( return tree; } -export function createMapFromList>( +export function createMapFromList( list: T[], - keySelector: (item: T) => NodeKey, - valueMapper = (item: T) => new TreeNode(item) as R, + keySelector: (item: T) => number | string | Symbol, + valueMapper: (item: T) => R, ) { - const map = new Map, ReturnType>(); + type Key = ReturnType; + type Value = NodeValue; + const map = new Map(); list.forEach(row => map.set(keySelector(row), valueMapper(row))); return map; } -type NodeKey = number | string | Symbol; - -interface BranchOrLeaf { - children: BranchOrLeaf[]; +export type TreeNode = { + [K in keyof T]: T[K]; +} & { + children: TreeNode[]; isLeaf: boolean; -} +}; + +type NodeValue any> = F extends undefined + ? TreeNode + : ReturnType;