From 002ee9e152a67c21c93ea986b9e527e6f6536307 Mon Sep 17 00:00:00 2001 From: Thijs Daniels Date: Wed, 14 Aug 2024 22:02:22 +0200 Subject: [PATCH] feat(essentials): add whereDefined and filterObject utilities --- .changeset/lemon-pumas-marry.md | 5 +++++ .../utilities/object/filterObject.test.ts | 13 ++++++++++++ .../utilities/object/filterObject.ts | 12 +++++++++++ .../utilities/object/whereDefined.test.ts | 20 +++++++++++++++++++ .../utilities/object/whereDefined.ts | 20 +++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 .changeset/lemon-pumas-marry.md create mode 100644 packages/essentials/utilities/object/filterObject.test.ts create mode 100644 packages/essentials/utilities/object/filterObject.ts create mode 100644 packages/essentials/utilities/object/whereDefined.test.ts create mode 100644 packages/essentials/utilities/object/whereDefined.ts diff --git a/.changeset/lemon-pumas-marry.md b/.changeset/lemon-pumas-marry.md new file mode 100644 index 00000000..84c686cf --- /dev/null +++ b/.changeset/lemon-pumas-marry.md @@ -0,0 +1,5 @@ +--- +"@codedazur/essentials": minor +--- + +The filterObject and whereDefined object utilities were added. diff --git a/packages/essentials/utilities/object/filterObject.test.ts b/packages/essentials/utilities/object/filterObject.test.ts new file mode 100644 index 00000000..4bcd91a2 --- /dev/null +++ b/packages/essentials/utilities/object/filterObject.test.ts @@ -0,0 +1,13 @@ +import { describe, it, expect } from "vitest"; +import { filterObject } from "./filterObject"; + +describe("filterObject", () => { + it("filters an object", () => { + expect( + filterObject( + { a: 1, b: 2, c: 3 }, + ([key, value]) => key === "a" || value === 3, + ), + ).toEqual({ a: 1, c: 3 }); + }); +}); diff --git a/packages/essentials/utilities/object/filterObject.ts b/packages/essentials/utilities/object/filterObject.ts new file mode 100644 index 00000000..3c5a47f4 --- /dev/null +++ b/packages/essentials/utilities/object/filterObject.ts @@ -0,0 +1,12 @@ +/** + * Filters an object by its entries. + */ +export function filterObject< + U extends Record, + T extends Record = Record, + K extends keyof T = keyof T, +>(object: T, callback: (entry: [K, T[K]]) => boolean): U { + return Object.fromEntries( + (Object.entries(object) as [K, T[K]][]).filter(callback), + ) as U; +} diff --git a/packages/essentials/utilities/object/whereDefined.test.ts b/packages/essentials/utilities/object/whereDefined.test.ts new file mode 100644 index 00000000..cf791649 --- /dev/null +++ b/packages/essentials/utilities/object/whereDefined.test.ts @@ -0,0 +1,20 @@ +import { describe, it, expect } from "vitest"; +import { whereDefined } from "./whereDefined"; + +describe("whereDefined", () => { + it("removes undefined properties", () => { + expect( + whereDefined({ + a: 0, + b: "", + c: false, + d: null, + e: undefined, + }), + ).toEqual({ + a: 0, + b: "", + c: false, + }); + }); +}); diff --git a/packages/essentials/utilities/object/whereDefined.ts b/packages/essentials/utilities/object/whereDefined.ts new file mode 100644 index 00000000..8c5044df --- /dev/null +++ b/packages/essentials/utilities/object/whereDefined.ts @@ -0,0 +1,20 @@ +import { filterObject } from "./filterObject"; + +/** + * Removes properties from an object that are `null` or `undefined`. + */ +export type WhereDefined = { + [P in keyof T]-?: NonNullable; +}; + +/** + * Removes properties from an object that are `null` or `undefined`. + */ +export function whereDefined>( + object: T, +): WhereDefined { + return filterObject( + object, + ([, value]) => value !== undefined && value !== null, + ); +}