Skip to content

Commit 8880673

Browse files
committed
feat(object-utilities): add fn to pick props + assert defined from object
1 parent 4162b15 commit 8880673

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

packages/utilities/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export * from './lib/json-stringify-replacer/json-stringify-replacer.function.js
99
export * from './lib/map-values-deep/map-values-deep.js'
1010
export * from './lib/object/omit-props.function.js'
1111
export * from './lib/object/pick-props.function.js'
12+
export * from './lib/object/pick-props-assert-defined.function.js'
1213
export * from './lib/promise/make-deferred.function.js'
1314
export * from './lib/math/clamp.function.js'
1415
export * from './lib/math/random-int.js'
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { pickPropsAssertDefined } from './pick-props-assert-defined.function.js'
2+
3+
describe('pickPropsAssertDefined', () => {
4+
test('returns object with picked props', () => {
5+
const obj = { a: true, b: 'foo', c: 42 }
6+
expect(pickPropsAssertDefined(obj, ['a', 'c'])).toEqual({ a: true, c: 42 })
7+
})
8+
test('throws when picked prop values are null or undefined', () => {
9+
const obj = { a: 'ok', b: null }
10+
expect(() => pickPropsAssertDefined(obj, ['a', 'b'])).toThrow(Error)
11+
})
12+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { isDefined } from '../ts-guards/is-defined.js'
2+
3+
export type PickedPropsDefined<T, K extends keyof T> = {
4+
[key in K]-?: NonNullable<T[key]>
5+
}
6+
7+
/**
8+
* returns an object containing the provided props with their respective value. throws if their value is null or undefined
9+
*/
10+
export function pickPropsAssertDefined<T, TProp extends keyof T>(
11+
obj: T,
12+
props: readonly TProp[],
13+
): PickedPropsDefined<T, TProp> {
14+
const entries = props.map((p) => {
15+
if (!isDefined(obj[p])) {
16+
throw new Error(`Expected property "${String(p)}" to be defined. Was "${String(obj[p])}" instead`)
17+
}
18+
return [p, obj[p]]
19+
})
20+
return Object.fromEntries(entries)
21+
}

0 commit comments

Comments
 (0)