Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

190
Views
How to remove keys and lift props up?

Given the following object:

{
  __proxy: {
    state: {
      count: 0
      items: {
        __proxy: {
          state: {
            amount: 0
          }
        }
      }
    }
  }
}

I'd like to convert it to:

{
  count: 0,
  items: {
    amount: 0
  }
}

So, as you can see, I'm doing a few things:

  1. Removing __proxy and bringing its content up
  2. Removing state and bringing its content up
  3. All of the above recursively.

I've tried something like the snippet below:

const removeKeys = (obj, keys) => obj !== Object(obj)
      ? obj
      : Array.isArray(obj)
      ? obj.map((item) => removeKeys(item, keys))
      : Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));

removeKeys(myObj, ['__proxy', 'state'])

However, it completely removes __proxy and/or state - and I want to preserve their content.

That said, do you know any existing solution for that? An NPM library, perhaps? Or a lodash function?

Note: Since I'm using TypeScript, a typed solution would be preferred, but raw js works well either.

Thanks!

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

You could destructure the unwanted properties and move the content a level up.

const
    convert = ({ __proxy, state, ...object }) => __proxy || state
        ? convert({ ...(__proxy || {}), ...(state || {}), ...object })
        : Object.fromEntries(Object
            .entries(object)
            .map(([k, v]) => [k, v && typeof v === 'object' ? convert(v) : v])
    )
    data = { __proxy: { state: { count: 0, items: { __proxy: { state: { amount: 0 } } } } } },
    result = convert(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

about 4 years ago · Juan Pablo Isaza Report

0

Usually for these problems I start on the types first. Sometimes making the type gives me ideas on how to implement it in code, so here we go!

Let's first define a type that does this (I call it "obliteration" for whatever reason) for one key only:

type Obliterate<O, K> = O extends object ? { [P in Exclude<keyof O, K>]: Obliterate<O[P], K> } & (K extends keyof O ? Obliterate<O[K], K> : {}) : O;

If O is not an object, there is nothing to remove from it.

However if it is, the following steps are taken:

  • We omit K from O and then recursively traverse down the object and "obliterate" all the values.
  • We check if K is a key of O and if it is we intersect it with the result from the first step. If it isn't we intersect it with {} which does nothing.

Then a type that takes a list of keys and iterates over it and uses Obliterate on the target:

type ObliterateEach<O, K> = K extends readonly [infer F, ...infer M] ? ObliterateEach<Obliterate<O, F>, M> : O;

If K is not empty, we operate on the object, otherwise we are done and return the object.

With these types I have poorly written the following code that both mirror how these types work:

const obliterate = <O, K extends PropertyKey>(o: O, k: K): Obliterate<O, K> => (
  (o && typeof o === "object")
    ? Object.assign(Object.fromEntries(Object.entries(o).filter(([p]) => p !== k).map(([p, v]) => [p, obliterate(v, k)])), k in o ? obliterate((o as any)[k], k) : {})
    : o
) as Obliterate<O, K>;

const obliterateEach = <O, K extends ReadonlyArray<PropertyKey>>(o: O, k: K): ObliterateEach<O, K> => (
  k.reduce<{}>((r, k) => obliterate(r, k), o)
)  as ObliterateEach<O, K>;

You can read these functions the same as the types above. They are the exact same steps, just in code and not types (and a few casts to suppress type errors).

This is most certainly not the best strongly typed solution, but it's a start.

A playground demonstrating this solution.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!