Рекурсия есть:
const sumNested = (data, getVal, key) => Object
  .entries(data instanceof Object ? data : {})
  .reduce((acc, [ k, v ]) => acc + sumNested(v, getVal, k), getVal(key, data));
const numItems = sumNested(obj, (k, v) => (k === 'items' && Array.isArray(v)) ? v.length : 0);
Рекурсии нет:
function sumNested(data, getVal) {
  let result = 0;
  for (const stack = [ [ , data ] ]; stack.length;) {
    const [ k, v ] = stack.pop();
    stack.push(...(v instanceof Object ? Object.entries(v) : []));
    result += getVal(k, v);
  }
  return result;
}