Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: deleteEmptyProperties 개선 #118

Merged
merged 2 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sour-hats-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modern-kit/utils': patch
---

fix: deleteFalsyProperties 개선
6 changes: 5 additions & 1 deletion docs/docs/utils/object/deleteEmptyProperties.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

## Interface
```ts title="typescript"
const deleteEmptyProperties: <T extends Record<PropertyKey, any>>(obj: T) => T
const deleteFalsyProperties: <
T extends Record<PropertyKey, any> = Record<PropertyKey, any>
>(
source: Record<PropertyKey, any>
) => T;
```

## Usage
Expand Down
25 changes: 25 additions & 0 deletions docs/docs/utils/validator/isArray.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# isArray

주어진 인자가 `배열`인지 검사하고, 맞다면 인자의 타입을 `Array`로 좁혀주는 함수입니다.

<br />

## Code
[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/utils/src/validator/isArray/index.ts)

## Interface
```ts title="typescript"
const isArray: <T>(value: unknown) => value is T[]
```

## Usage
```ts title="typescript"
import { isArray } from '@modern-kit/utils';

isArray([]); // true

isArray(() => {}); // false
isArray('123'); // false
isArray(123); // false
isArray({}); // false
```
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('deleteFalsyProperties', () => {
],
},
},
prop3: [1, 2, null],
};
const expectedObj = {
prop1: [
Expand All @@ -73,6 +74,7 @@ describe('deleteFalsyProperties', () => {
prop2_1_6: [{ prop2_1_6_1: 1 }],
},
},
prop3: [1, 2],
};

expect(deleteFalsyProperties(originObj)).toEqual(expectedObj);
Expand Down Expand Up @@ -118,4 +120,30 @@ describe('deleteFalsyProperties', () => {
prop10: {},
});
});

it('should allow specifying desired types through generics', () => {
const originObj = {
prop1: 1,
prop2: 0,
prop3: '',
prop4: '1',
prop5: true,
prop6: false,
prop7: null,
prop8: undefined,
prop9: [],
prop10: {},
};
const expectedObj = {
prop1: 1,
prop2: 0,
prop4: '1',
prop5: true,
prop6: false,
};

const result = deleteFalsyProperties<typeof expectedObj>(originObj);

expectTypeOf(result).toEqualTypeOf<typeof expectedObj>();
});
});
22 changes: 13 additions & 9 deletions packages/utils/src/object/deleteFalsyProperties/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { hasProperty } from '../../validator';
import { hasProperty, isArray } from '../../validator';

export const deleteFalsyProperties = <T extends Record<PropertyKey, any>>(
source: T
export const deleteFalsyProperties = <
T extends Record<PropertyKey, any> = Record<PropertyKey, any>
>(
source: Record<PropertyKey, any>
): T => {
const copiedObj: Record<PropertyKey, any> = {};

for (const key in source) {
if (hasProperty(source, key)) {
const value = source[key];

if (value !== null && typeof value === 'object') {
if (value != null && typeof value === 'object') {
// object
if (!Array.isArray(value)) {
if (!isArray(value)) {
const newObj = deleteFalsyProperties(value);
const isNonEmptyObj = !!Object.keys(newObj).length;

if (Object.keys(newObj).length) {
if (isNonEmptyObj) {
copiedObj[key] = newObj;
}
continue;
}

// array
const newArray = value.reduce((acc: any[], cur: any) => {
if (typeof cur !== 'object') {
Expand All @@ -36,14 +40,14 @@ export const deleteFalsyProperties = <T extends Record<PropertyKey, any>>(
copiedObj[key] = newArray;
}
} else if (
value ||
typeof value === 'number' ||
typeof value === 'boolean' ||
value
typeof value === 'boolean'
) {
copiedObj[key] = value;
}
}
}

return copiedObj;
return copiedObj as T;
};
1 change: 1 addition & 0 deletions packages/utils/src/validator/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './hasProperty';
export * from './isArray';
export * from './isFunction';
export * from './isNotNullish';
export * from './isNullish';
Expand Down
3 changes: 3 additions & 0 deletions packages/utils/src/validator/isArray/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const isArray = <T>(value: unknown): value is Array<T> => {
return Array.isArray(value);
};
20 changes: 20 additions & 0 deletions packages/utils/src/validator/isArray/isArray.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { isArray } from '.';

describe('isArray', () => {
it('should return true if the argument is an array, and false if it is not', () => {
expect(isArray([])).toBeTruthy();
expect(isArray(1)).toBeFalsy();
expect(isArray('')).toBeFalsy();
expect(isArray({})).toBeFalsy();
});

it('should narrow the type through if statements', () => {
const testValue = ['foo'] as string | string[];

if (isArray<string>(testValue)) {
expectTypeOf(testValue).toEqualTypeOf<string[]>();
} else {
expectTypeOf(testValue).toEqualTypeOf<string>();
}
});
});