Implement deepOmit(value, keys) — return a copy of value with the given keys stripped from every nested object at every depth. This is the recursive cousin of lodash's omit: instead of dropping keys only at the top level, you walk the whole tree and drop the same forbidden names wherever they appear. The common use case is sanitising a payload before you log it or send it across the wire — strip password, token, and secret once, anywhere they sit in a nested config, response, or audit blob.
// Returns a structural copy of `value` with every occurrence of any key in
// `keys` removed — at any depth. Arrays are walked; their items keep their
// own keys filtered. Primitives are returned as-is. Input is never mutated.
function deepOmit<T>(value: T, keys: string[]): T;
// Omit a single key at the top level.
deepOmit({ a: 1, b: 2 }, ['a']);
// → { b: 2 }
// Omit the same key from every depth at once.
deepOmit({ a: 1, b: { a: 2, c: 3 } }, ['a']);
// → { b: { c: 3 } }
// `a` is gone from BOTH levels — including the nested object.
// Walk into arrays; their item objects still get filtered.
deepOmit({ users: [{ id: 1, password: 'x' }, { id: 2, password: 'y' }] }, ['password']);
// → { users: [{ id: 1 }, { id: 2 }] }
// The array stays an array; only the inner objects lose `password`.
keys.Array.isArray(value) is your branch: for an array, map each element through deepOmit so the recursion continues into nested objects.number, string, boolean, null, undefined), Date, RegExp, Map, Set, and anything else that isn't a plain {} or [] is opaque — return it without copying. The shape of the tree is {} | [] | leaf.{} or [] at every level you descend into; the caller's original tree must look identical after the call.keys is an array of strings. Symbol keys are out of scope — skipping them is acceptable. Use a Set for the lookup so the per-key check is O(1), not O(n).deepOmit({ a: 1 }, ['nope']) returns { a: 1 }. No throwing, no warning.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.