diff --git a/.changeset/hot-cameras-clean.md b/.changeset/hot-cameras-clean.md new file mode 100644 index 000000000..e54b59054 --- /dev/null +++ b/.changeset/hot-cameras-clean.md @@ -0,0 +1,6 @@ +--- +'@modern-kit/types': minor +'@modern-kit/utils': minor +--- + +feat(utils): isPrimitive 함수 추가 및 Primitive, Reference 유틸 타입 추가 - @ssi02014 diff --git a/docs/docs/utils/validator/isPrimitive.md b/docs/docs/utils/validator/isPrimitive.md new file mode 100644 index 000000000..af0ee5bd1 --- /dev/null +++ b/docs/docs/utils/validator/isPrimitive.md @@ -0,0 +1,39 @@ +# isPrimitive + +주어진 인자가 `원시값`인지 검사하고, 맞다면 인자의 타입을 `Primitive`로 좁혀주는 함수입니다. + +
+ +## 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 +``` \ No newline at end of file diff --git a/packages/types/src/Primitive/Primitive.spec.ts b/packages/types/src/Primitive/Primitive.spec.ts new file mode 100644 index 000000000..0a259c681 --- /dev/null +++ b/packages/types/src/Primitive/Primitive.spec.ts @@ -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(); + } + + if (typeof value === 'string') { + expectTypeOf(value).toEqualTypeOf(); + } + + if (typeof value === 'boolean') { + expectTypeOf(value).toEqualTypeOf(); + } + + if (typeof value === 'symbol') { + expectTypeOf(value).toEqualTypeOf(); + } + + if (typeof value === 'bigint') { + expectTypeOf(value).toEqualTypeOf(); + } + + if (value === null) { + expectTypeOf(value).toEqualTypeOf(); + } + + if (value === undefined) { + expectTypeOf(value).toEqualTypeOf(); + } + }); +}); diff --git a/packages/types/src/Primitive/index.ts b/packages/types/src/Primitive/index.ts new file mode 100644 index 000000000..2192e750a --- /dev/null +++ b/packages/types/src/Primitive/index.ts @@ -0,0 +1,8 @@ +export type Primitive = + | string + | number + | boolean + | symbol + | bigint + | null + | undefined; diff --git a/packages/types/src/Reference/Primitive.spec.ts b/packages/types/src/Reference/Primitive.spec.ts new file mode 100644 index 000000000..dcfe895f7 --- /dev/null +++ b/packages/types/src/Reference/Primitive.spec.ts @@ -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>(); + } + + if (Array.isArray(value)) { + expectTypeOf(value).toEqualTypeOf(); + } + + if (typeof value === 'function') { + expectTypeOf(value).toEqualTypeOf any)>(); + } + + if (value instanceof Set) { + expectTypeOf(value).toEqualTypeOf>(); + } + + if (value instanceof Map) { + expectTypeOf(value).toEqualTypeOf>(); + } + + if (value instanceof WeakMap) { + expectTypeOf(value).toEqualTypeOf>(); + } + + if (value instanceof WeakSet) { + expectTypeOf(value).toEqualTypeOf>(); + } + + if (value instanceof Date) { + expectTypeOf(value).toEqualTypeOf(); + } + + if (value instanceof RegExp) { + expectTypeOf(value).toEqualTypeOf(); + } + + if (value instanceof Error) { + expectTypeOf(value).toEqualTypeOf(); + } + }); +}); diff --git a/packages/types/src/Reference/index.ts b/packages/types/src/Reference/index.ts new file mode 100644 index 000000000..a36c1bfcd --- /dev/null +++ b/packages/types/src/Reference/index.ts @@ -0,0 +1,11 @@ +export type Reference = + | object + | any[] + | ((...args: any[]) => any) + | Set + | Map + | WeakMap + | WeakSet + | Date + | RegExp + | Error; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 9eff652fc..1528dbc2a 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -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'; diff --git a/packages/utils/src/validator/index.ts b/packages/utils/src/validator/index.ts index fe0092288..bcfc56434 100644 --- a/packages/utils/src/validator/index.ts +++ b/packages/utils/src/validator/index.ts @@ -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'; diff --git a/packages/utils/src/validator/isPrimitive/index.ts b/packages/utils/src/validator/isPrimitive/index.ts new file mode 100644 index 000000000..12fccc072 --- /dev/null +++ b/packages/utils/src/validator/isPrimitive/index.ts @@ -0,0 +1,5 @@ +import { Primitive } from '@modern-kit/types'; + +export const isPrimitive = (value: unknown): value is Primitive => { + return Object(value) !== value; +}; diff --git a/packages/utils/src/validator/isPrimitive/isPrimitive.spec.ts b/packages/utils/src/validator/isPrimitive/isPrimitive.spec.ts new file mode 100644 index 000000000..eb60082ad --- /dev/null +++ b/packages/utils/src/validator/isPrimitive/isPrimitive.spec.ts @@ -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(); + + if (isNumber(value)) { + expectTypeOf(value).toEqualTypeOf(); + } + + if (isString(value)) { + expectTypeOf(value).toEqualTypeOf(); + } + } else { + expectTypeOf(value).toEqualTypeOf(); + } + }); +});