-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change should have no impact on functionality. This replaces the following pattern: ```javascript // eslint-disable-next-line no-unused-vars const { foo, bar, ...rest } = obj return rest ``` With a new `omit` utility, which I think is clearer: ```javascript return omit(obj, ['foo', 'bar']) ``` I think this is a useful change on its own, but also makes an upcoming change slightly easier because I wanted this function.
- Loading branch information
Showing
10 changed files
with
123 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* Returns a new object with the own enumerable keys of `obj` that are not in `keys`. | ||
* | ||
* In other words, remove some keys from an object. | ||
* | ||
* @template {object} T | ||
* @template {keyof T} K | ||
* @param {T} obj | ||
* @param {ReadonlyArray<K>} keys | ||
* @returns {Omit<T, K>} | ||
* @example | ||
* const obj = { foo: 1, bar: 2, baz: 3 } | ||
* omit(obj, ['foo', 'bar']) | ||
* // => { baz: 3 } | ||
*/ | ||
export function omit(obj, keys) { | ||
/** @type {Partial<T>} */ const result = {} | ||
|
||
/** @type {Set<unknown>} */ const toOmit = new Set(keys) | ||
|
||
for (const key in obj) { | ||
if (!Object.hasOwn(obj, key)) continue | ||
if (toOmit.has(key)) continue | ||
result[key] = obj[key] | ||
} | ||
|
||
return /** @type {Omit<T, K>} */ (result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import test from 'node:test' | ||
import assert from 'node:assert/strict' | ||
import { omit } from '../../src/lib/omit.js' | ||
|
||
test('an empty list of keys to omit', () => { | ||
assert.deepEqual(omit({}, []), {}) | ||
assert.deepEqual(omit({ foo: 1 }, []), { foo: 1 }) | ||
}) | ||
|
||
test('omitting non-existent properties', () => { | ||
assert.deepEqual(omit(record(), ['foo', 'bar']), {}) | ||
assert.deepEqual(omit(record({ foo: 1 }), ['bar', 'baz']), { foo: 1 }) | ||
}) | ||
|
||
test('omitting properties', () => { | ||
const obj = { foo: 1, bar: 2, baz: 3 } | ||
assert.deepEqual(omit(obj, ['baz']), { foo: 1, bar: 2 }) | ||
assert.deepEqual(omit(obj, ['bar', 'baz']), { foo: 1 }) | ||
}) | ||
|
||
test('only includes "own" properties in the result', () => { | ||
class Klass { | ||
foo = 1 | ||
bar = 2 | ||
baz() { | ||
return 3 | ||
} | ||
} | ||
|
||
const omitted = omit(new Klass(), ['bar']) | ||
assert.deepEqual(omitted, { foo: 1 }, 'plain object is returned') | ||
assert(!(omitted instanceof Klass), 'inheritance is lost after omitting') | ||
assert(!('baz' in omitted), 'inherited properties are lost after omitting') | ||
|
||
const obj = new Klass() | ||
obj.baz = () => 4 | ||
assert.equal(omit(obj, [])?.baz(), 4, 'own properties can be kept') | ||
assert(!('baz' in omit(obj, ['baz'])), 'own properties can be removed') | ||
}) | ||
|
||
test('only includes enumerable properties', () => { | ||
const obj = { foo: 1 } | ||
Object.defineProperty(obj, 'bar', { enumerable: true, value: 2 }) | ||
Object.defineProperty(obj, 'baz', { enumerable: false, value: 3 }) | ||
|
||
assert.deepEqual(omit(obj, ['foo']), { bar: 2 }) | ||
}) | ||
|
||
test("doesn't modify the input", () => { | ||
const obj = { foo: 1, bar: 2, baz: 3 } | ||
omit(obj, []) | ||
omit(obj, ['foo', 'bar']) | ||
assert.deepEqual( | ||
obj, | ||
{ foo: 1, bar: 2, baz: 3 }, | ||
'input should not be modified' | ||
) | ||
}) | ||
|
||
/** | ||
* Convenience helper to satisfy TypeScript. | ||
* @param {Record<string, unknown>} [result] | ||
* @returns {Record<string, unknown>} | ||
*/ | ||
const record = (result = {}) => result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters