Skip to content

Commit

Permalink
removeUndefinedProperties replaced with removeNullableProperties func…
Browse files Browse the repository at this point in the history
…tion and return type narrowed to NonNullableProperties<T> type
  • Loading branch information
nelsonni committed Feb 22, 2023
1 parent 1f8d999 commit a926884
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/containers/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,14 @@ describe('containers/utils', () => {
expect(utils.removeObjectProperty(obj, 'c')).toStrictEqual({ a: 3, b: 'alpha' });
});

it('removeUndefinedProperties removes undefined from Object of Primitive types', () => {
it('removeNullableProperties removes undefined from Object of Primitive types', () => {
const obj = { a: 3, b: 'a', c: undefined, d: true };
expect(utils.removeUndefinedProperties(obj)).toStrictEqual({ a: 3, b: 'a', d: true });
expect(utils.removeNullableProperties(obj)).toStrictEqual({ a: 3, b: 'a', d: true });
});

it('removeUndefinedProperties removes top-level undefined from Object with nested Objects', () => {
it('removeNullableProperties removes top-level undefined from Object with nested Objects', () => {
const obj = { a: undefined, b: { c: 3 }, d: { e: undefined }, f: { g: 7 } };
expect(utils.removeUndefinedProperties(obj)).toStrictEqual({ b: { c: 3 }, d: { e: undefined }, f: { g: 7 } });
expect(utils.removeNullableProperties(obj)).toStrictEqual({ b: { c: 3 }, d: { e: undefined }, f: { g: 7 } });
});

it('removeDuplicates removes duplicates from array of Primitive types', () => {
Expand Down
20 changes: 9 additions & 11 deletions src/containers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ export type Nullable<T> = {
};

/**
* Requires properties to be defined, or excluded from the type otherwise. Allows for empty object.
* Requires properties to be non-nullable (i.e. `null` or `undefined` or `void`), or excluded from the subsequent type. Allows for empty objects.
* Inspired by: https://stackoverflow.com/a/60574436
*/
export type NonUndefinedProperties<T> = {
[P in keyof T]-?: Exclude<T[P], null | undefined | void>;
} | Record<string, never>;
export type NonNullableProperties<T> = { [P in keyof T as T[P] extends undefined | null ? never : P]: T[P] };

/**
* Requires at least one type property, similar to `Partial<T>` but excludes the empty object.
Expand Down Expand Up @@ -241,16 +239,16 @@ export const removeObjectProperty = <V, T extends Record<string, V>, K extends k
}

/**
* Filters an object and removes any properties with undefined values.
* Filters an object and removes any properties with nullable values (`undefined` | `null` | `void`).
*
* @param obj The given object containing key-value properties that should be filtered for undefined.
* @returns {object} The resulting object devoid of any undefined values.
* @param obj The given object containing key-value properties that should be filtered for nullable values.
* @returns {object} The resulting object devoid of any nullable values.
*/
export const removeUndefinedProperties = <V, T extends Record<string, V | undefined | null | void>>(obj: T): NonUndefinedProperties<T> => {
export const removeNullableProperties = <V, T extends Record<string | number | symbol, V>>(obj: T): NonNullableProperties<T> => {
return Object.entries(obj)
.filter((e): e is [string, V] => isPresent(e[1]))
.reduce((accumulator, [k, v]) => ({ ...accumulator, [k]: v }), {});
}
.filter((e): e is [string, NonNullable<V>] => e[1] !== undefined && e[1] !== null)
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {} as NonNullableProperties<T>);
};

/**
* Generic for deduplicating array of elements given a comparator function that
Expand Down

0 comments on commit a926884

Please sign in to comment.