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

feat(utils): isPrimitive 함수 추가 및 Primitive, Reference 유틸 타입 추가 #217

Merged
merged 3 commits into from
Jun 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
6 changes: 6 additions & 0 deletions .changeset/hot-cameras-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@modern-kit/types': minor
'@modern-kit/utils': minor
---

feat(utils): isPrimitive 함수 추가 및 Primitive, Reference 유틸 타입 추가 - @ssi02014
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ module.exports = {
'import/no-anonymous-default-export': 'off',
'no-useless-escape': 'off',
'react/react-in-jsx-scope': 'off',
'@typescript-eslint/ban-types': 'warn',
},
};
39 changes: 39 additions & 0 deletions docs/docs/utils/validator/isPrimitive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# isPrimitive

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

<br />

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

## Interface
```ts title="typescript"
type Primitive =
| string
| number
| boolean
| symbol
| bigint
| null
| undefined;

const isPrimitive: (value: unknown) => value is Primitive
```

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

isPrimitive(123); // true
isPrimitive('123'); // true
isPrimitive(true); // true
isPrimitive(Symbol()); // true
isPrimitive(null); // true
isPrimitive(undefined); // true

isPrimitive({}); // false
isPrimitive([]); // false
isPrimitive(new Set()); // false
isPrimitive(new Map()); // false
```
35 changes: 35 additions & 0 deletions packages/types/src/Primitive/Primitive.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Primitive } from '.';

describe('Primitive', () => {
it('should properly infer the type', () => {
const value = 1 as Primitive;

if (typeof value === 'number') {
expectTypeOf(value).toEqualTypeOf<number>();
}

if (typeof value === 'string') {
expectTypeOf(value).toEqualTypeOf<string>();
}

if (typeof value === 'boolean') {
expectTypeOf(value).toEqualTypeOf<boolean>();
}

if (typeof value === 'symbol') {
expectTypeOf(value).toEqualTypeOf<symbol>();
}

if (typeof value === 'bigint') {
expectTypeOf(value).toEqualTypeOf<bigint>();
}

if (value === null) {
expectTypeOf(value).toEqualTypeOf<null>();
}

if (value === undefined) {
expectTypeOf(value).toEqualTypeOf<undefined>();
}
});
});
8 changes: 8 additions & 0 deletions packages/types/src/Primitive/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type Primitive =
| string
| number
| boolean
| symbol
| bigint
| null
| undefined;
47 changes: 47 additions & 0 deletions packages/types/src/Reference/Primitive.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Reference } from '.';

describe('Reference', () => {
it('should properly infer the type', () => {
const value = {} as Reference;

if (typeof value === 'object') {
expectTypeOf(value).toEqualTypeOf<Exclude<Reference, Function>>();
}

if (Array.isArray(value)) {
expectTypeOf(value).toEqualTypeOf<any[]>();
}

if (typeof value === 'function') {
expectTypeOf(value).toEqualTypeOf<Function>();
}

if (value instanceof Set) {
expectTypeOf(value).toEqualTypeOf<Set<any>>();
}

if (value instanceof Map) {
expectTypeOf(value).toEqualTypeOf<Map<any, any>>();
}

if (value instanceof WeakMap) {
expectTypeOf(value).toEqualTypeOf<WeakMap<object, any>>();
}

if (value instanceof WeakSet) {
expectTypeOf(value).toEqualTypeOf<WeakSet<object>>();
}

if (value instanceof Date) {
expectTypeOf(value).toEqualTypeOf<Date>();
}

if (value instanceof RegExp) {
expectTypeOf(value).toEqualTypeOf<RegExp>();
}

if (value instanceof Error) {
expectTypeOf(value).toEqualTypeOf<Error>();
}
});
});
11 changes: 11 additions & 0 deletions packages/types/src/Reference/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type Reference =
| object
| any[]
| Function
| Set<any>
| Map<any, any>
| WeakMap<object, any>
| WeakSet<object>
| Date
| RegExp
| Error;
2 changes: 2 additions & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export * from './IndexSignature';
export * from './Nullable';
export * from './ObjectEntries';
export * from './ObjectKeys';
export * from './Primitive';
export * from './Promiseable';
export * from './Integer';
export * from './Reference';
export * from './NaturalNumber';
export * from './WholeNumber';
1 change: 1 addition & 0 deletions packages/utils/src/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './isFunction';
export * from './isNotNullish';
export * from './isNullish';
export * from './isNumber';
export * from './isPrimitive';
export * from './isPromise';
export * from './isString';
export * from './isValidEmail';
Expand Down
5 changes: 5 additions & 0 deletions packages/utils/src/validator/isPrimitive/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Primitive } from '@modern-kit/types';

export const isPrimitive = (value: unknown): value is Primitive => {
return Object(value) !== value;
};
39 changes: 39 additions & 0 deletions packages/utils/src/validator/isPrimitive/isPrimitive.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Primitive } from '@modern-kit/types';
import { isPrimitive } from '.';
import { isNumber } from '../isNumber';
import { isString } from '../isString';

describe('isPrimitive', () => {
it('should return true if the value is a primitive type, and false if it is a reference type', () => {
expect(isPrimitive(null)).toBeTruthy();
expect(isPrimitive(undefined)).toBeTruthy();
expect(isPrimitive(1)).toBeTruthy();
expect(isPrimitive(BigInt(1))).toBeTruthy();
expect(isPrimitive('')).toBeTruthy();
expect(isPrimitive(false)).toBeTruthy();
expect(isPrimitive(Symbol())).toBeTruthy();

expect(isPrimitive([])).toBeFalsy();
expect(isPrimitive({})).toBeFalsy();
expect(isPrimitive(new Set())).toBeFalsy();
expect(isPrimitive(new Map())).toBeFalsy();
});

it('should properly infer the type', () => {
const value = 1 as unknown;

if (isPrimitive(value)) {
expectTypeOf(value).toEqualTypeOf<Primitive>();

if (isNumber(value)) {
expectTypeOf(value).toEqualTypeOf<number>();
}

if (isString(value)) {
expectTypeOf(value).toEqualTypeOf<string>();
}
} else {
expectTypeOf(value).toEqualTypeOf<unknown>();
}
});
});