Skip to content

Commit

Permalink
fix: keep prototype null-ness
Browse files Browse the repository at this point in the history
If the subject is created using `record()`,
`pick()` and `omit()` will maintain that.
  • Loading branch information
unional committed Oct 13, 2022
1 parent b7628cb commit af54c8e
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
9 changes: 7 additions & 2 deletions ts/object/omit.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertType, Equal, Except, isType, Omit, omit } from '../index.js'
import { assertType, Equal, Except, isType, Omit, omit, record } from '../index.js'

describe('Omit<T, K>', () => {
test('work with primitive types', () => {
Expand Down Expand Up @@ -92,12 +92,17 @@ describe(`${omit.name}()`, () => {
isType.equal<true, Record<string, any>, typeof r>()
})

it('more than 12', () => {
it('supports more than 12 arguments', () => {
const actual = omit({ a: 1, b: 1, c: 1 }, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b')

expect(actual).toEqual({ c: 1 })
assertType.isTrue(true as Equal<keyof typeof actual, 'c'>)
})

it('maintains the prototype null-ness', () => {
expect(Object.getPrototypeOf(omit({ a: 1 }, 'a'))).not.toEqual(null)
expect(Object.getPrototypeOf(omit(record({ a: 1 }), 'a'))).toEqual(null)
})
})

describe('Except()', () => {
Expand Down
5 changes: 3 additions & 2 deletions ts/object/omit.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AnyRecord, record, reduceByKey } from '../object/index.js'
import { AnyRecord, reduceByKey } from '../object/index.js'
import { UnionKeys } from '../UnionKeys.js'
import { Pick } from './pick.js'
import { record } from './record.js'

// by Titian Cernicova-Dragomir
// https://github.com/microsoft/TypeScript/issues/28339#issuecomment-463577347
Expand Down Expand Up @@ -33,5 +34,5 @@ export function omit<T extends AnyRecord>(subject: T, ...props: Array<UnionKeys<
return reduceByKey(subject, (p, k) => {
if (props.indexOf(k) === -1) p[k] = subject[k]
return p
}, record())
}, Object.getPrototypeOf(subject) === null ? record() : {})
}
31 changes: 22 additions & 9 deletions ts/object/pick.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
import { assertType, canAssign, Equal, Pick, pick } from '../index.js'

describe(`${pick.name}()`, () => {
it('picks properties from object', () => {
const actual = pick({ a: 1, b: 2 }, 'a')

expect(actual).toEqual({ a: 1 })
})
})
import { assertType, canAssign, Equal, isType, Pick, pick, record } from '../index.js'

describe(`Pick<T, K>`, () => {
test('distributive pick', () => {
Expand Down Expand Up @@ -68,3 +60,24 @@ describe(`Pick<T, K>`, () => {
assertType.isTrue(true as Equal<K, never>)
})
})

describe(`${pick.name}()`, () => {
it('picks properties from object', () => {
const actual = pick({ a: 1, b: 2 }, 'a')

expect(actual).toEqual({ a: 1 })
})

it('supports more than 12 arguments', () => {
const actual = pick({ a: 1, b: 1, c: 1 }, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b')

expect(actual).toEqual({ a: 1, b: 1 })
isType.equal<true, 'a' | 'b', keyof typeof actual>()
})

it('maintains the prototype null-ness', () => {
expect(Object.getPrototypeOf(pick({ a: 1 }, 'a'))).not.toEqual(null)
expect(Object.getPrototypeOf(pick(record({ a: 1 }), 'a'))).toEqual(null)
})
})

4 changes: 2 additions & 2 deletions ts/object/pick.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { record } from 'type-plus'
import { UnionKeys } from '../UnionKeys.js'
import type { AnyRecord } from './AnyRecord.js'
import { record } from './record.js'
import { reduceByKey } from './reduceKey.js'

export function pick<T extends AnyRecord, P1 extends UnionKeys<T>>(subject: T, prop1: P1): Pick<T, P1>
Expand All @@ -20,7 +20,7 @@ export function pick<T extends AnyRecord>(subject: T, ...props: Array<UnionKeys<
return reduceByKey(subject, (p, k) => {
if (props.indexOf(k) >= 0) p[k] = subject[k]
return p
}, record())
}, Object.getPrototypeOf(subject) === null ? record() : {})
}

/**
Expand Down

0 comments on commit af54c8e

Please sign in to comment.