import * as R from 'ramda'; type BaseT = Record; export const pickAll = ( key: string, childKey: string, data: T[] | T, ): any[] => { const hasChildren = (node: T) => { return R.hasPath([childKey], node); }; const Tree: any = { reduce: R.curry((reducerFn: any, init: any[], node: T) => { const acc = reducerFn(init, node); if (!hasChildren(node)) { const res = acc && acc.length ? R.map((item: any) => { return item[key] || item })(acc) : []; return res; } return node[childKey] ? node[childKey].reduce(Tree.reduce(reducerFn), acc) : acc; }), find: R.curry((findFn: any, init: any[], node: T[]) => { return R.pipe(R.map(Tree.reduce(findFn, init)), R.flatten)(node as T[]); }) }; const fn = (arr: any[], data: T) => { if (data[key]) { return arr.concat([R.omit([childKey], data)]); } else { return arr; } }; const type = R.type(data); switch (type) { case 'Object': { return Tree.reduce(fn, [])(data); } case 'Array': { return Tree.find(fn, [])(data); } default: { return data as T[]; } } };