From a52354a15a6626c76c52425d46082e9ce465e70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Tesa=C5=99?= Date: Sun, 3 Nov 2019 01:44:09 +0100 Subject: [PATCH] Fix wrong types in set and update (#13) --- docs/globals.html | 34 +++++++++++++++++----------------- docs/index.html | 34 +++++++++++++++++----------------- package.json | 3 ++- src/lib/set.ts | 16 +++++++++------- src/lib/update.ts | 20 ++++++++++++-------- src/test/set.test.ts | 13 +++++++++++++ src/test/update.test.ts | 13 +++++++++++++ tsconfig.json | 2 +- 8 files changed, 84 insertions(+), 51 deletions(-) diff --git a/docs/globals.html b/docs/globals.html index 09a1c73..7ebe001 100644 --- a/docs/globals.html +++ b/docs/globals.html @@ -2597,7 +2597,7 @@

Nullable

Nullable<T>: T | null

Type parameters

@@ -2613,7 +2613,7 @@

Optional

Optional<T>: T | null | undefined

Type parameters

@@ -2629,7 +2629,7 @@

Undefinable

Undefinable<T>: T | undefined

Type parameters

@@ -2645,7 +2645,7 @@

UnwrapOptional

UnwrapOptional<T>: Exclude<T, null | undefined>

Type parameters

@@ -2661,7 +2661,7 @@

Without

Without<T, K>: Without<T, K>

Type parameters

@@ -2683,7 +2683,7 @@

Const exist

exist: ExistFn = existImplementation
@@ -2712,7 +2712,7 @@

Const filter

filter: FilterFn = filterImplementation
@@ -2743,7 +2743,7 @@

Const get

get: GetFn = getImplementation
@@ -2779,7 +2779,7 @@

Const map

map: MapFn = mapImplementation
@@ -2812,7 +2812,7 @@

Const omit

omit: OmitFn = omitImplementation
@@ -2844,7 +2844,7 @@

Const pick

pick: PickFn = pickImplementation
@@ -2876,7 +2876,7 @@

Const set

set: SetFn = setImplementation
@@ -2912,7 +2912,7 @@

Const unset

unset: UnsetFn = unsetImplementation
@@ -2943,7 +2943,7 @@

Const update

update: UpdateFn = updateImplementation
@@ -2985,7 +2985,7 @@

isNullOrUndefined

  • Parameters

    @@ -3008,7 +3008,7 @@

    isObject

  • Parameters

    @@ -3031,7 +3031,7 @@

    shallowCopy

  • Parameters

    diff --git a/docs/index.html b/docs/index.html index cedb58a..d7fb333 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2598,7 +2598,7 @@

    Nullable

    Nullable<T>: T | null

    Type parameters

    @@ -2614,7 +2614,7 @@

    Optional

    Optional<T>: T | null | undefined

    Type parameters

    @@ -2630,7 +2630,7 @@

    Undefinable

    Undefinable<T>: T | undefined

    Type parameters

    @@ -2646,7 +2646,7 @@

    UnwrapOptional

    UnwrapOptional<T>: Exclude<T, null | undefined>

    Type parameters

    @@ -2662,7 +2662,7 @@

    Without

    Without<T, K>: Without<T, K>

    Type parameters

    @@ -2684,7 +2684,7 @@

    Const exist

    exist: ExistFn = existImplementation
    @@ -2713,7 +2713,7 @@

    Const filter

    filter: FilterFn = filterImplementation
    @@ -2744,7 +2744,7 @@

    Const get

    get: GetFn = getImplementation
    @@ -2780,7 +2780,7 @@

    Const map

    map: MapFn = mapImplementation
    @@ -2813,7 +2813,7 @@

    Const omit

    omit: OmitFn = omitImplementation
    @@ -2845,7 +2845,7 @@

    Const pick

    pick: PickFn = pickImplementation
    @@ -2877,7 +2877,7 @@

    Const set

    set: SetFn = setImplementation
    @@ -2913,7 +2913,7 @@

    Const unset

    unset: UnsetFn = unsetImplementation
    @@ -2944,7 +2944,7 @@

    Const update

    update: UpdateFn = updateImplementation
    @@ -2986,7 +2986,7 @@

    isNullOrUndefined

  • Parameters

    @@ -3009,7 +3009,7 @@

    isObject

  • Parameters

    @@ -3032,7 +3032,7 @@

    shallowCopy

  • Parameters

    diff --git a/package.json b/package.json index dd5e6b1..2f3d88c 100644 --- a/package.json +++ b/package.json @@ -44,5 +44,6 @@ "homepage": "https://github.com/Siegrift/tsfunct#readme", "directories": { "doc": "docs" - } + }, + "dependencies": {} } diff --git a/src/lib/set.ts b/src/lib/set.ts index f0eba82..520eaa2 100644 --- a/src/lib/set.ts +++ b/src/lib/set.ts @@ -4,12 +4,12 @@ import { isObject, shallowCopy } from '../utils' type Set1 = T extends any[] ? T : Pick> & - { [KK1 in K1]-?: Required> }[K1] + { [KK1 in K1]-?: Required>[KK1] } type Set2> = T extends any[] ? T : Pick> & - { [KK1 in K1]-?: Required<{ [key in K1]: Set1, K2> }> }[K1] + { [KK1 in K1]-?: Required<{ [key in K1]: Set1, K2> }>[KK1] } type Set3< T, @@ -19,7 +19,7 @@ type Set3< > = T extends any[] ? T : Pick> & - { [KK1 in K1]-?: Required<{ [key in K1]: Set2, K2, K3> }> }[K1] + { [KK1 in K1]-?: Required<{ [key in K1]: Set2, K2, K3> }>[KK1] } type Set4< T, @@ -31,8 +31,10 @@ type Set4< ? T : Pick> & { - [KK1 in K1]-?: Required<{ [key in K1]: Set3, K2, K3, K4> }>; - }[K1] + [KK1 in K1]-?: Required< + { [key in K1]: Set3, K2, K3, K4> } + >[KK1]; + } type Set5< T, @@ -47,8 +49,8 @@ type Set5< { [KK1 in K1]-?: Required< { [key in K1]: Set4, K2, K3, K4, K5> } - >; - }[K1] + >[KK1]; + } interface SetFn { (source: Optional, path: [K1], value: T[K1]): Set1< diff --git a/src/lib/update.ts b/src/lib/update.ts index 90fe650..68e2a89 100644 --- a/src/lib/update.ts +++ b/src/lib/update.ts @@ -4,12 +4,12 @@ import { isObject, shallowCopy } from '../utils' type Update1 = T extends any[] ? T : Pick> & - { [KK1 in K1]-?: Required> }[K1] + { [KK1 in K1]-?: Required>[KK1] } type Update2> = T extends any[] ? T : Pick> & - { [KK1 in K1]-?: Required<{ [key in K1]: Update1, K2> }> }[K1] + { [KK1 in K1]-?: Required<{ [key in K1]: Update1, K2> }>[KK1] } type Update3< T, @@ -20,8 +20,10 @@ type Update3< ? T : Pick> & { - [KK1 in K1]-?: Required<{ [key in K1]: Update2, K2, K3> }>; - }[K1] + [KK1 in K1]-?: Required< + { [key in K1]: Update2, K2, K3> } + >[KK1]; + } type Update4< T, @@ -33,8 +35,10 @@ type Update4< ? T : Pick> & { - [KK1 in K1]-?: Required<{ [key in K1]: Update3, K2, K3, K4> }>; - }[K1] + [KK1 in K1]-?: Required< + { [key in K1]: Update3, K2, K3, K4> } + >[KK1]; + } type Update5< T, @@ -49,8 +53,8 @@ type Update5< { [KK1 in K1]-?: Required< { [key in K1]: Update4, K2, K3, K4, K5> } - >; - }[K1] + >[KK1]; + } interface UpdateFn { ( diff --git a/src/test/set.test.ts b/src/test/set.test.ts index a319cae..ade45df 100644 --- a/src/test/set.test.ts +++ b/src/test/set.test.ts @@ -128,5 +128,18 @@ describe('set', () => { const newObj: A = set(obj, ['a', 'b'], false) expect(newObj).toEqual({ a: { b: false, c: {} }, d: 'str' }) }) + + test('works with union of properties', () => { + interface A { + a: 'fixed' + b: string + c: boolean + } + const obj: A = { a: 'fixed', b: 'str', c: true } + const prop = 'a' as 'a' | 'b' + + const s: A = set(obj, [prop], 'fixed') + expect(s).toEqual(obj) + }) }) }) diff --git a/src/test/update.test.ts b/src/test/update.test.ts index 2bfc4b8..6afb57e 100644 --- a/src/test/update.test.ts +++ b/src/test/update.test.ts @@ -147,4 +147,17 @@ describe('update', () => { const newState = update(state, ['optional', 'a'], (op) => 123) expect(newState.optional.a).toBe(123) // the path surely exists now! }) + + test('works with union of properties', () => { + interface A { + a: string + b: number + c: boolean + } + const obj: A = { a: 'str', b: 123, c: true } + const prop = 'a' as 'a' | 'b' + + const upd: A = update(obj, [prop], (val) => val) + expect(upd).toEqual(obj) + }) }) diff --git a/tsconfig.json b/tsconfig.json index 5d0840c..05c7b0a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,7 +39,7 @@ "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */