diff --git a/docs/globals.html b/docs/globals.html index f9f9054..dda3437 100644 --- a/docs/globals.html +++ b/docs/globals.html @@ -100,6 +100,7 @@

Functions

  • filter
  • get
  • isNullOrUndefined
  • +
  • isObject
  • map
  • omit
  • pick
  • @@ -192,7 +193,7 @@

    U

    Undefinable

    -
    Undefinable: T | null
    +
    Undefinable: T | undefined
    +
    + +

    isObject

    + + +

    map

    @@ -3812,7 +3836,7 @@

    set

  • @@ -3861,7 +3885,7 @@

    Returns T<
  • @@ -3913,7 +3937,7 @@

    Returns T<
  • @@ -3968,7 +3992,7 @@

    Returns T<
  • @@ -4026,7 +4050,7 @@

    Returns T<
  • @@ -4096,7 +4120,7 @@

    shallowCopy

  • Parameters

    @@ -4116,6 +4140,11 @@

    Returns any

    unset

      +
    • unset<T, K1>(source: T, path: [K1]): Unset1<T, K1>
    • +
    • unset<T, K1, K2>(source: T, path: [K1, K2]): Unset2<T, K1, K2>
    • +
    • unset<T, K1, K2, K3>(source: T, path: [K1, K2, K3]): Unset3<T, K1, K2, K3>
    • +
    • unset<T, K1, K2, K3, K4>(source: T, path: [K1, K2, K3, K4]): Unset4<T, K1, K2, K3, K4>
    • +
    • unset<T, K1, K2, K3, K4, K5>(source: T, path: [K1, K2, K3, K4, K5]): Unset5<T, K1, K2, K3, K4, K5>
    • unset<T, K1>(source: Nullable<T>, path: [K1]): Nullable<Unset1<T, K1>>
    • unset<T, K1, K2>(source: Nullable<T>, path: [K1, K2]): Nullable<Unset2<T, K1, K2>>
    • unset<T, K1, K2, K3>(source: Nullable<T>, path: [K1, K2, K3]): Nullable<Unset3<T, K1, K2, K3>>
    • @@ -4131,11 +4160,6 @@

      unset

    • unset<T, K1, K2, K3>(source: Optional<T>, path: [K1, K2, K3]): Optional<Unset3<T, K1, K2, K3>>
    • unset<T, K1, K2, K3, K4>(source: Optional<T>, path: [K1, K2, K3, K4]): Optional<Unset4<T, K1, K2, K3, K4>>
    • unset<T, K1, K2, K3, K4, K5>(source: Optional<T>, path: [K1, K2, K3, K4, K5]): Optional<Unset5<T, K1, K2, K3, K4, K5>>
    • -
    • unset<T, K1>(source: T, path: [K1]): Unset1<T, K1>
    • -
    • unset<T, K1, K2>(source: T, path: [K1, K2]): Unset2<T, K1, K2>
    • -
    • unset<T, K1, K2, K3>(source: T, path: [K1, K2, K3]): Unset3<T, K1, K2, K3>
    • -
    • unset<T, K1, K2, K3, K4>(source: T, path: [K1, K2, K3, K4]): Unset4<T, K1, K2, K3, K4>
    • -
    • unset<T, K1, K2, K3, K4, K5>(source: T, path: [K1, K2, K3, K4, K5]): Unset5<T, K1, K2, K3, K4, K5>
    • @@ -4166,7 +4190,7 @@

      K1: Parameters

      • -
        source: Nullable<T>
        +
        source: T

        source, in which the nested value should be removed.

        @@ -4178,7 +4202,7 @@
        path: [Returns Nullable<Unset1<T, K1>>
        +

        Returns Unset1<T, K1>

        source value with removed value

      • @@ -4212,7 +4236,7 @@

        K2: Parameters

        • -
          source: Nullable<T>
          +
          source: T

          source, in which the nested value should be removed.

          @@ -4224,7 +4248,7 @@
          path: [Returns Nullable<Unset2<T, K1, K2>>
          +

          Returns Unset2<T, K1, K2>

          source value with removed value

        • @@ -4261,7 +4285,7 @@

          K3: Parameters

          • -
            source: Nullable<T>
            +
            source: T

            source, in which the nested value should be removed.

            @@ -4273,7 +4297,7 @@
            path: [Returns Nullable<Unset3<T, K1, K2, K3>>
            +

            Returns Unset3<T, K1, K2, K3>

            source value with removed value

          • @@ -4313,7 +4337,7 @@

            K4: Parameters

            • -
              source: Nullable<T>
              +
              source: T

              source, in which the nested value should be removed.

              @@ -4325,13 +4349,13 @@
              path: [Returns Nullable<Unset4<T, K1, K2, K3, K4>>
              +

              Returns Unset4<T, K1, K2, K3, K4>

              source value with removed value

            • @@ -4368,7 +4392,7 @@

              K5: Parameters

              • -
                source: Nullable<T>
                +
                source: T

                source, in which the nested value should be removed.

                @@ -4380,13 +4404,13 @@
                path: [Returns Nullable<Unset5<T, K1, K2, K3, K4, K5>>
                +

                Returns Unset5<T, K1, K2, K3, K4, K5>

                source value with removed value

              • @@ -4411,7 +4435,7 @@

                K1: Parameters

                • -
                  source: Undefinable<T>
                  +
                  source: Nullable<T>

                  source, in which the nested value should be removed.

                  @@ -4423,13 +4447,13 @@
                  path: [Returns Undefinable<Unset1<T, K1>>
                  +

                  Returns Nullable<Unset1<T, K1>>

                  source value with removed value

                • @@ -4457,7 +4481,7 @@

                  K2: Parameters

                  • -
                    source: Undefinable<T>
                    +
                    source: Nullable<T>

                    source, in which the nested value should be removed.

                    @@ -4469,13 +4493,13 @@
                    path: [Returns Undefinable<Unset2<T, K1, K2>>
                    +

                    Returns Nullable<Unset2<T, K1, K2>>

                    source value with removed value

                  • @@ -4506,7 +4530,7 @@

                    K3: Parameters

                    • -
                      source: Undefinable<T>
                      +
                      source: Nullable<T>

                      source, in which the nested value should be removed.

                      @@ -4518,13 +4542,13 @@
                      path: [Returns Undefinable<Unset3<T, K1, K2, K3>>
                      +

                      Returns Nullable<Unset3<T, K1, K2, K3>>

                      source value with removed value

                    • @@ -4558,7 +4582,7 @@

                      K4: Parameters

                      • -
                        source: Undefinable<T>
                        +
                        source: Nullable<T>

                        source, in which the nested value should be removed.

                        @@ -4570,13 +4594,13 @@
                        path: [Returns Undefinable<Unset4<T, K1, K2, K3, K4>>
                        +

                        Returns Nullable<Unset4<T, K1, K2, K3, K4>>

                        source value with removed value

                      • @@ -4613,7 +4637,7 @@

                        K5: Parameters

                        • -
                          source: Undefinable<T>
                          +
                          source: Nullable<T>

                          source, in which the nested value should be removed.

                          @@ -4625,13 +4649,13 @@
                          path: [Returns Undefinable<Unset5<T, K1, K2, K3, K4, K5>>
                          +

                          Returns Nullable<Unset5<T, K1, K2, K3, K4, K5>>

                          source value with removed value

                        • @@ -4656,7 +4680,7 @@

                          K1: Parameters

                          • -
                            source: Optional<T>
                            +
                            source: Undefinable<T>

                            source, in which the nested value should be removed.

                            @@ -4668,13 +4692,13 @@
                            path: [Returns Optional<Unset1<T, K1>>
                            +

                            Returns Undefinable<Unset1<T, K1>>

                            source value with removed value

                          • @@ -4702,7 +4726,7 @@

                            K2: Parameters

                            • -
                              source: Optional<T>
                              +
                              source: Undefinable<T>

                              source, in which the nested value should be removed.

                              @@ -4714,13 +4738,13 @@
                              path: [Returns Optional<Unset2<T, K1, K2>>
                              +

                              Returns Undefinable<Unset2<T, K1, K2>>

                              source value with removed value

                            • @@ -4751,7 +4775,7 @@

                              K3: Parameters

                              • -
                                source: Optional<T>
                                +
                                source: Undefinable<T>

                                source, in which the nested value should be removed.

                                @@ -4763,13 +4787,13 @@
                                path: [Returns Optional<Unset3<T, K1, K2, K3>>
                                +

                                Returns Undefinable<Unset3<T, K1, K2, K3>>

                                source value with removed value

                              • @@ -4803,7 +4827,7 @@

                                K4: Parameters

                                • -
                                  source: Optional<T>
                                  +
                                  source: Undefinable<T>

                                  source, in which the nested value should be removed.

                                  @@ -4815,13 +4839,13 @@
                                  path: [Returns Optional<Unset4<T, K1, K2, K3, K4>>
                                  +

                                  Returns Undefinable<Unset4<T, K1, K2, K3, K4>>

                                  source value with removed value

                                • @@ -4858,7 +4882,7 @@

                                  K5: Parameters

                                  • -
                                    source: Optional<T>
                                    +
                                    source: Undefinable<T>

                                    source, in which the nested value should be removed.

                                    @@ -4870,13 +4894,13 @@
                                    path: [Returns Optional<Unset5<T, K1, K2, K3, K4, K5>>
                                    +

                                    Returns Undefinable<Unset5<T, K1, K2, K3, K4, K5>>

                                    source value with removed value

                                  • @@ -4901,7 +4925,7 @@

                                    K1: Parameters

                                    • -
                                      source: T
                                      +
                                      source: Optional<T>

                                      source, in which the nested value should be removed.

                                      @@ -4913,13 +4937,13 @@
                                      path: [Returns Unset1<T, K1>
                                      +

                                      Returns Optional<Unset1<T, K1>>

                                      source value with removed value

                                    • @@ -4947,7 +4971,7 @@

                                      K2: Parameters

                                      • -
                                        source: T
                                        +
                                        source: Optional<T>

                                        source, in which the nested value should be removed.

                                        @@ -4959,13 +4983,13 @@
                                        path: [Returns Unset2<T, K1, K2>
                                        +

                                        Returns Optional<Unset2<T, K1, K2>>

                                        source value with removed value

                                      • @@ -4996,7 +5020,7 @@

                                        K3: Parameters

                                        • -
                                          source: T
                                          +
                                          source: Optional<T>

                                          source, in which the nested value should be removed.

                                          @@ -5008,13 +5032,13 @@
                                          path: [Returns Unset3<T, K1, K2, K3>
                                          +

                                          Returns Optional<Unset3<T, K1, K2, K3>>

                                          source value with removed value

                                        • @@ -5048,7 +5072,7 @@

                                          K4: Parameters

                                          • -
                                            source: T
                                            +
                                            source: Optional<T>

                                            source, in which the nested value should be removed.

                                            @@ -5060,13 +5084,13 @@
                                            path: [Returns Unset4<T, K1, K2, K3, K4>
                                            +

                                            Returns Optional<Unset4<T, K1, K2, K3, K4>>

                                            source value with removed value

                                          • @@ -5103,7 +5127,7 @@

                                            K5: Parameters

                                            • -
                                              source: T
                                              +
                                              source: Optional<T>

                                              source, in which the nested value should be removed.

                                              @@ -5115,7 +5139,7 @@
                                              path: [Returns Unset5<T, K1, K2, K3, K4, K5>
                                              +

                                              Returns Optional<Unset5<T, K1, K2, K3, K4, K5>>

                                              source value with removed value

                                            @@ -5134,7 +5158,7 @@

                                            update

                                          • @@ -5200,7 +5224,7 @@

                                            Returns T<
                                          • @@ -5269,7 +5293,7 @@

                                            Returns T<
                                          • @@ -5341,7 +5365,7 @@

                                            Returns T<
                                          • @@ -5416,7 +5440,7 @@

                                            Returns T<
                                          • @@ -5565,6 +5589,9 @@

                                            Returns T<
                                          • isNullOrUndefined
                                          • +
                                          • + isObject +
                                          • map
                                          • diff --git a/docs/index.html b/docs/index.html index c003f98..7cd05ef 100644 --- a/docs/index.html +++ b/docs/index.html @@ -196,6 +196,9 @@

                                            Limitations

                                          • isNullOrUndefined
                                          • +
                                          • + isObject +
                                          • map
                                          • diff --git a/docs/interfaces/dictionary.html b/docs/interfaces/dictionary.html index 7ffff9a..798bf27 100644 --- a/docs/interfaces/dictionary.html +++ b/docs/interfaces/dictionary.html @@ -161,6 +161,9 @@

                                            Indexable

                                          • isNullOrUndefined
                                          • +
                                          • + isObject +
                                          • map
                                          • diff --git a/docs/interfaces/numericdictionary.html b/docs/interfaces/numericdictionary.html index 3c04a23..9e9ed38 100644 --- a/docs/interfaces/numericdictionary.html +++ b/docs/interfaces/numericdictionary.html @@ -161,6 +161,9 @@

                                            Indexable

                                          • isNullOrUndefined
                                          • +
                                          • + isObject +
                                          • map
                                          • diff --git a/src/lib/exist.ts b/src/lib/exist.ts index d5a20a8..40aeaef 100644 --- a/src/lib/exist.ts +++ b/src/lib/exist.ts @@ -1,5 +1,6 @@ import { Optional, U } from '../types' import { isNullOrUndefined } from 'util' +import { isObject } from '../utils' /** * Checks whether path exist in source value. @@ -101,7 +102,7 @@ export function exist(source: any, path: any[]) { while (++index < path.length) { if ( isNullOrUndefined(source) || - typeof source !== 'object' || + !isObject(source) || !source.hasOwnProperty(path[index]) ) { return false diff --git a/src/lib/set.ts b/src/lib/set.ts index a9d1f7b..4376193 100644 --- a/src/lib/set.ts +++ b/src/lib/set.ts @@ -1,5 +1,6 @@ import { Optional, U } from '../types' import { shallowCopy } from '../utils' +import { isObject } from 'util' /** * Sets the value on the specified path in source value. If the path in the source doesn't exist it @@ -122,13 +123,13 @@ export function set< // NOTE: implementation export function set(source: any, path: any[], value: any) { - const returnObject = shallowCopy(source, Array.isArray(path[0]) ? [] : {}) + const returnObject = shallowCopy(source, Number.isInteger(path[0]) ? [] : {}) let currentObject = returnObject let index = 0 while (index < path.length) { if ( !Array.isArray(currentObject[path[index]]) && - typeof currentObject[path[index]] !== 'object' + !isObject(currentObject[path[index]]) ) { currentObject[path[index]] = Number.isInteger(path[index + 1]) ? [] : {} } diff --git a/src/lib/unset.ts b/src/lib/unset.ts index a61f2a7..1ee8e82 100644 --- a/src/lib/unset.ts +++ b/src/lib/unset.ts @@ -32,9 +32,9 @@ type Unset5 = { * @returns source value with removed value */ export function unset( - source: Nullable, + source: T, path: [K1], -): Nullable> +): Unset1 /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -51,9 +51,9 @@ export function unset( * @returns source value with removed value */ export function unset>( - source: Nullable, + source: T, path: [K1, K2], -): Nullable> +): Unset2 /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -74,7 +74,7 @@ export function unset< K1 extends keyof T, K2 extends keyof U, K3 extends keyof U[K2]> ->(source: Nullable, path: [K1, K2, K3]): Nullable> +>(source: T, path: [K1, K2, K3]): Unset3 /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -96,10 +96,7 @@ export function unset< K2 extends keyof U, K3 extends keyof U[K2]>, K4 extends keyof U[K2]>[K3]> ->( - source: Nullable, - path: [K1, K2, K3, K4], -): Nullable> +>(source: T, path: [K1, K2, K3, K4]): Unset4 /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -122,10 +119,7 @@ export function unset< K3 extends keyof U[K2]>, K4 extends keyof U[K2]>[K3]>, K5 extends keyof U[K2]>[K3]>[K4]> ->( - source: Nullable, - path: [K1, K2, K3, K4, K5], -): Nullable> +>(source: T, path: [K1, K2, K3, K4, K5]): Unset5 /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -142,9 +136,9 @@ export function unset< * @returns source value with removed value */ export function unset( - source: Undefinable, + source: Nullable, path: [K1], -): Undefinable> +): Nullable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -161,9 +155,9 @@ export function unset( * @returns source value with removed value */ export function unset>( - source: Undefinable, + source: Nullable, path: [K1, K2], -): Undefinable> +): Nullable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -184,10 +178,7 @@ export function unset< K1 extends keyof T, K2 extends keyof U, K3 extends keyof U[K2]> ->( - source: Undefinable, - path: [K1, K2, K3], -): Undefinable> +>(source: Nullable, path: [K1, K2, K3]): Nullable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -210,9 +201,9 @@ export function unset< K3 extends keyof U[K2]>, K4 extends keyof U[K2]>[K3]> >( - source: Undefinable, + source: Nullable, path: [K1, K2, K3, K4], -): Undefinable> +): Nullable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -236,9 +227,9 @@ export function unset< K4 extends keyof U[K2]>[K3]>, K5 extends keyof U[K2]>[K3]>[K4]> >( - source: Undefinable, + source: Nullable, path: [K1, K2, K3, K4, K5], -): Undefinable> +): Nullable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -255,9 +246,9 @@ export function unset< * @returns source value with removed value */ export function unset( - source: Optional, + source: Undefinable, path: [K1], -): Optional> +): Undefinable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -274,9 +265,9 @@ export function unset( * @returns source value with removed value */ export function unset>( - source: Optional, + source: Undefinable, path: [K1, K2], -): Optional> +): Undefinable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -297,7 +288,10 @@ export function unset< K1 extends keyof T, K2 extends keyof U, K3 extends keyof U[K2]> ->(source: Optional, path: [K1, K2, K3]): Optional> +>( + source: Undefinable, + path: [K1, K2, K3], +): Undefinable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -320,9 +314,9 @@ export function unset< K3 extends keyof U[K2]>, K4 extends keyof U[K2]>[K3]> >( - source: Optional, + source: Undefinable, path: [K1, K2, K3, K4], -): Optional> +): Undefinable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -346,9 +340,9 @@ export function unset< K4 extends keyof U[K2]>[K3]>, K5 extends keyof U[K2]>[K3]>[K4]> >( - source: Optional, + source: Undefinable, path: [K1, K2, K3, K4, K5], -): Optional> +): Undefinable> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -365,9 +359,9 @@ export function unset< * @returns source value with removed value */ export function unset( - source: T, + source: Optional, path: [K1], -): Unset1 +): Optional> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -384,9 +378,9 @@ export function unset( * @returns source value with removed value */ export function unset>( - source: T, + source: Optional, path: [K1, K2], -): Unset2 +): Optional> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -407,7 +401,7 @@ export function unset< K1 extends keyof T, K2 extends keyof U, K3 extends keyof U[K2]> ->(source: T, path: [K1, K2, K3]): Unset3 +>(source: Optional, path: [K1, K2, K3]): Optional> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -429,7 +423,10 @@ export function unset< K2 extends keyof U, K3 extends keyof U[K2]>, K4 extends keyof U[K2]>[K3]> ->(source: T, path: [K1, K2, K3, K4]): Unset4 +>( + source: Optional, + path: [K1, K2, K3, K4], +): Optional> /** * Removes the value on the specified path in source value. If the value is an array, the behavior @@ -452,7 +449,10 @@ export function unset< K3 extends keyof U[K2]>, K4 extends keyof U[K2]>[K3]>, K5 extends keyof U[K2]>[K3]>[K4]> ->(source: T, path: [K1, K2, K3, K4, K5]): Unset5 +>( + source: Optional, + path: [K1, K2, K3, K4, K5], +): Optional> // NOTE: implementation export function unset(source: any, path: any[]) { diff --git a/src/lib/update.ts b/src/lib/update.ts index 42b23bc..47de1be 100644 --- a/src/lib/update.ts +++ b/src/lib/update.ts @@ -1,5 +1,6 @@ import { DeepReadonly, Optional, U } from '../types' import { shallowCopy } from '../utils' +import { isObject } from 'util' /** * Updates the value on the specified path in source value using update function. This function will @@ -140,13 +141,13 @@ export function update< // NOTE: implementation export function update(source: any, path: any[], updateFn: any) { - const returnObject = shallowCopy(source, Array.isArray(path[0]) ? [] : {}) + const returnObject = shallowCopy(source, Number.isInteger(path[0]) ? [] : {}) let currentObject = returnObject let index = 0 while (index < path.length) { if ( !Array.isArray(currentObject[path[index]]) && - typeof currentObject[path[index]] !== 'object' + !isObject(currentObject[path[index]]) ) { currentObject[path[index]] = Number.isInteger(path[index + 1]) ? [] : {} } diff --git a/src/test/set.test.ts b/src/test/set.test.ts index 18e0edf..ea51543 100644 --- a/src/test/set.test.ts +++ b/src/test/set.test.ts @@ -85,14 +85,21 @@ describe('set', () => { }) }) - test('if path is number an array is created, otherwise object is created', () => { - type A = string[] - type D = { [key: string]: A } - type T = { req: { opt?: D | null } } - const obj: T = { req: { opt: null } } + describe('if path is number an array is created, otherwise object is created', () => { + test('correct root value', () => { + expect(set(null as any, ['hello'], 'str')).toEqual({ hello: 'str' }) + expect(set(null as any, [1], 'str')).toEqual([undefined, 'str']) + }) + + test('deep path', () => { + type A = string[] + type D = { [key: string]: A } + type T = { req: { opt?: D | null } } + const obj: T = { req: { opt: null } } - expect(set(obj, ['req', 'opt', 'key', 1], 'str')).toEqual({ - req: { opt: { key: [undefined, 'str'] } }, + expect(set(obj, ['req', 'opt', 'key', 1], 'str')).toEqual({ + req: { opt: { key: [undefined, 'str'] } }, + }) }) }) }) diff --git a/src/test/update.test.ts b/src/test/update.test.ts index c4393fd..5581b21 100644 --- a/src/test/update.test.ts +++ b/src/test/update.test.ts @@ -101,14 +101,26 @@ describe('update', () => { }) }) - test('if path is number an array is created, otherwise object is created', () => { - type A = string[] - type D = { [key: string]: A } - type T = { req: { opt?: D | null } } - const obj: T = { req: { opt: null } } + describe('if path is number an array is created, otherwise object is created', () => { + test('correct root value', () => { + expect(update(null as any, ['hello'], () => 'str')).toEqual({ + hello: 'str', + }) + expect(update(null as any, [1], () => 'str')).toEqual([ + undefined, + 'str', + ]) + }) + + test('deep path', () => { + type A = string[] + type D = { [key: string]: A } + type T = { req: { opt?: D | null } } + const obj: T = { req: { opt: null } } - expect(update(obj, ['req', 'opt', 'key', 1], () => 'str')).toEqual({ - req: { opt: { key: [undefined, 'str'] } }, + expect(update(obj, ['req', 'opt', 'key', 1], () => 'str')).toEqual({ + req: { opt: { key: [undefined, 'str'] } }, + }) }) }) }) diff --git a/src/types.ts b/src/types.ts index cc25d46..a679fd8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,7 +8,7 @@ export type DeepReadonlyObject = { export type Nullable = T | null -export type Undefinable = T | null +export type Undefinable = T | undefined export type Optional = T | null | undefined diff --git a/src/utils.test.ts b/src/utils.test.ts new file mode 100644 index 0000000..43fbdc9 --- /dev/null +++ b/src/utils.test.ts @@ -0,0 +1,54 @@ +import { isObject, shallowCopy } from './utils' + +describe('utils', () => { + describe('isObject', () => { + test('returns true when the value is object', () => { + expect(isObject({})).toBe(true) + expect(isObject([1, 2, 3])).toBe(true) + expect(isObject(Function)).toBe(true) + + expect(isObject(123)).toBe(false) + expect(isObject(undefined)).toBe(false) + expect(isObject(false)).toBe(false) + expect(isObject(true)).toBe(false) + expect(isObject('str')).toBe(false) + }) + + test('null is not object', () => { + expect(isObject(null)).toBe(false) + }) + }) + + describe('shallowCopy', () => { + test('primitive values', () => { + expect(shallowCopy(123)).toBe(123) + expect(shallowCopy(undefined)).toBe(undefined) + expect(shallowCopy(null)).toBe(null) + expect(shallowCopy(false)).toBe(false) + expect(shallowCopy(true)).toBe(true) + expect(shallowCopy('str')).toBe('str') + }) + + test('object', () => { + // result needs to be shallow copy + expect(shallowCopy({ a: true })).not.toBe({ a: true }) + expect(shallowCopy({ a: true })).toEqual({ a: true }) + + // nested levels are the same + const nested = { nested: 'str' } + const obj = { top: nested } + expect(shallowCopy(obj).top).toBe(nested) + }) + + test('array', () => { + // result needs to be shallow copy + expect(shallowCopy([true])).not.toBe([true]) + expect(shallowCopy([true])).toEqual([true]) + + // nested levels are the same + const nested = { nested: 'str' } + const arr = [nested] + expect(shallowCopy(arr)[0]).toBe(nested) + }) + }) +}) diff --git a/src/utils.ts b/src/utils.ts index d7bbf40..cba68eb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,8 +2,17 @@ export function isNullOrUndefined(arg: any): arg is null | undefined { return arg === null || arg === undefined } +export function isObject(value: any): boolean { + const type = typeof value + return value !== null && (type === 'object' || type === 'function') +} + export function shallowCopy(value: any, defaultValue?: any) { + const _default = defaultValue === undefined ? value : defaultValue + // because (typeof null === "object") + if (value === null) return _default + if (Array.isArray(value)) return [...value] - if (typeof value === 'object') return { ...value } - return defaultValue === undefined ? value : defaultValue + if (isObject(value)) return { ...value } + return _default }