From 8045f8aae6f5823b9bbfe4adc958f4c8fe32c9d7 Mon Sep 17 00:00:00 2001 From: jero Date: Sun, 6 Oct 2019 23:09:48 +0300 Subject: [PATCH] refactor(utils): rename appendProps to pluckProps apply correct typing BREAKING CHANGE: appendProps is now renamed pluckProps --- src/app/shared/utils/pluckProps/index.tsx | 1 + .../utils/pluckProps/pluckProps.test.tsx | 52 +++++++++++++++++++ .../shared/utils/pluckProps/pluckProps.tsx | 17 ++++++ 3 files changed, 70 insertions(+) create mode 100644 src/app/shared/utils/pluckProps/index.tsx create mode 100644 src/app/shared/utils/pluckProps/pluckProps.test.tsx create mode 100644 src/app/shared/utils/pluckProps/pluckProps.tsx diff --git a/src/app/shared/utils/pluckProps/index.tsx b/src/app/shared/utils/pluckProps/index.tsx new file mode 100644 index 00000000..2c57bc9e --- /dev/null +++ b/src/app/shared/utils/pluckProps/index.tsx @@ -0,0 +1 @@ +export { default } from './pluckProps'; diff --git a/src/app/shared/utils/pluckProps/pluckProps.test.tsx b/src/app/shared/utils/pluckProps/pluckProps.test.tsx new file mode 100644 index 00000000..ef65bc21 --- /dev/null +++ b/src/app/shared/utils/pluckProps/pluckProps.test.tsx @@ -0,0 +1,52 @@ +import pluckProps from './pluckProps'; + +type Obj = { + a: 1; + b: 2; +}; + +describe('pluckProps', () => { + it('should return a function', () => { + const fn = pluckProps('a'); + expect(typeof fn).toEqual('function'); + }); + + it('should return an object with property "a" and ignore the rest', () => { + const fn = pluckProps('a'); + const obj = fn({ a: 1, b: 2 }); + expect(obj).toEqual({ a: 1 }); + }); + + it('should return an object with properties "a" and "b"', () => { + const fn = pluckProps('a', 'b'); + const obj = fn({ a: 1, b: 2 }); + expect(obj).toEqual({ a: 1, b: 2 }); + }); + + it('should return an object with property "b"', () => { + const fn = pluckProps('b'); + const obj = fn({ a: 1, b: 2 }); + expect(obj).toEqual({ b: 2 }); + }); + + // eslint-disable-next-line prettier/prettier + it('should return empty object if the given object doesn\'t match with properties to reflect', () => { + const fn = pluckProps('a', 'b'); + const obj = fn({ c: 3, d: 4 }); + expect(obj).toEqual({}); + }); + + // eslint-disable-next-line prettier/prettier + it('should return empty object if there\'s not properties to append', () => { + const fn = pluckProps(); + const obj = fn({ a: 1, b: 2 }); + expect(obj).toEqual({}); + }); + // eslint-disable-next-line prettier/prettier + it('should throw if there\'s not object to reflect', () => { + const fn = pluckProps('a', 'b'); + expect(() => { + fn(); + }).toThrow(); + }); +}); diff --git a/src/app/shared/utils/pluckProps/pluckProps.tsx b/src/app/shared/utils/pluckProps/pluckProps.tsx new file mode 100644 index 00000000..357aaf6a --- /dev/null +++ b/src/app/shared/utils/pluckProps/pluckProps.tsx @@ -0,0 +1,17 @@ +/** + * @desc: conditionally append properties as they're defined + */ + +type AppendProps = (...args: Array) => (obj: T) => T | Partial; + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +const pluckProps: AppendProps = (...args) => obj => + args.reduce( + (acc, arg) => ({ + ...acc, + ...(obj[arg] && { [arg]: obj[arg] }), + }), + {}, + ); + +export default pluckProps;