@@ -7,11 +7,12 @@ import { emptyMap } from '../Map';
7
7
import { get } from './get' ;
8
8
import { remove } from './remove' ;
9
9
import { set } from './set' ;
10
- import type { KeyPath , update } from '../../type-definitions/immutable' ;
11
-
12
- type UpdaterFunction = ( value : unknown ) => unknown ;
13
-
14
- type UpdateTypeParameters = Parameters < typeof update > ;
10
+ import type {
11
+ Collection ,
12
+ KeyPath ,
13
+ Record ,
14
+ RetrievePath ,
15
+ } from '../../type-definitions/immutable' ;
15
16
16
17
/**
17
18
* Returns a copy of the collection with the value at key path set to the
@@ -29,30 +30,115 @@ type UpdateTypeParameters = Parameters<typeof update>;
29
30
* console.log(original) // { x: { y: { z: 123 }}}
30
31
* ```
31
32
*/
32
- export function updateIn < C extends UpdateTypeParameters [ 0 ] > (
33
+
34
+ export type PossibleCollection < K ,
F438
V , TProps extends object > =
35
+ | Collection < K , V >
36
+ | Record < TProps >
37
+ | Array < V > ;
38
+
39
+ type UpdaterFunction < K extends PropertyKey , C > = (
40
+ value : RetrievePath < C , Array < K > > | undefined
41
+ ) => unknown | undefined ;
42
+ type UpdaterFunctionWithNSV < K extends PropertyKey , C , NSV > = (
43
+ value : RetrievePath < C , Array < K > > | NSV
44
+ ) => unknown ;
45
+
46
+ export function updateIn < K extends PropertyKey , V , C extends Collection < K , V > > (
33
47
collection : C ,
34
- keyPath : KeyPath < UpdateTypeParameters [ 1 ] > ,
35
- updater : UpdateTypeParameters [ 2 ]
48
+ keyPath : KeyPath < K > ,
49
+ updater : UpdaterFunction < K , C >
36
50
) : C ;
37
- export function updateIn < C extends UpdateTypeParameters [ 0 ] > (
51
+ export function updateIn <
52
+ K extends PropertyKey ,
53
+ V ,
54
+ C extends Collection < K , V > ,
55
+ NSV ,
56
+ > (
38
57
collection : C ,
39
- keyPath : KeyPath < UpdateTypeParameters [ 1 ] > ,
40
- notSetValue : UpdateTypeParameters [ 2 ] ,
41
- updater : UpdateTypeParameters [ 3 ]
58
+ keyPath : KeyPath < K > ,
59
+ notSetValue : NSV ,
60
+ updater : UpdaterFunctionWithNSV < K , C , NSV >
61
+ ) : C ;
62
+ export function updateIn <
63
+ TProps extends object ,
64
+ C extends Record < TProps > ,
65
+ K extends keyof TProps ,
66
+ > ( record : C , keyPath : KeyPath < K > , updater : UpdaterFunction < K , C > ) : C ;
67
+ export function updateIn <
68
+ TProps extends object ,
69
+ C extends Record < TProps > ,
70
+ K extends keyof TProps ,
71
+ NSV ,
72
+ > (
73
+ record : C ,
74
+ keyPath : KeyPath < K > ,
75
+ notSetValue : NSV ,
76
+ updater : UpdaterFunctionWithNSV < K , C , NSV >
42
77
) : C ;
43
- export function updateIn < C extends UpdateTypeParameters [ 0 ] > (
78
+ export function updateIn < K extends PropertyKey , V , C extends Array < V > > (
79
+ collection : C ,
80
+ keyPath : KeyPath < string | number > ,
81
+ updater : UpdaterFunction < K , C >
82
+ ) : Array < V > ;
83
+ export function updateIn < K extends PropertyKey , V , C extends Array < V > , NSV > (
84
+ collection : C ,
85
+ keyPath : KeyPath < K > ,
86
+ notSetValue : NSV ,
87
+ updater : UpdaterFunctionWithNSV < K , C , NSV >
88
+ ) : Array < V > ;
89
+ export function updateIn < K extends PropertyKey , C > (
90
+ object : C ,
91
+ keyPath : KeyPath < K > ,
92
+ updater : UpdaterFunction < K , C >
93
+ ) : C ;
94
+ export function updateIn < K extends PropertyKey , C , NSV > (
95
+ object : C ,
96
+ keyPath : KeyPath < K > ,
97
+ notSetValue : NSV ,
98
+ updater : UpdaterFunctionWithNSV < K , C , NSV >
99
+ ) : C ;
100
+ export function updateIn <
101
+ K extends PropertyKey ,
102
+ V ,
103
+ C extends { [ key : PropertyKey ] : V } ,
104
+ > (
105
+ collection : C ,
106
+ keyPath : KeyPath < K > ,
107
+ updater : UpdaterFunction < K , C >
108
+ ) : { [ key : PropertyKey ] : V } ;
109
+ export function updateIn <
110
+ K extends PropertyKey ,
111
+ V ,
112
+ C extends { [ key : PropertyKey ] : V } ,
113
+ NSV ,
114
+ > (
115
+ collection : C ,
116
+ keyPath : KeyPath < K > ,
117
+ notSetValue : NSV ,
118
+ updater : UpdaterFunction < K , C >
119
+ ) : { [ key : PropertyKey ] : V } ;
120
+
121
+ export function updateIn <
122
+ K extends PropertyKey ,
123
+ V ,
124
+ TProps extends object ,
125
+ C extends PossibleCollection < K , V , TProps > ,
126
+ NSV ,
127
+ > (
44
128
collection : C ,
45
- keyPath : KeyPath < UpdateTypeParameters [ 1 ] > ,
46
- notSetValue : UpdateTypeParameters [ 2 ] ,
47
- updater ?: UpdateTypeParameters [ 3 ]
129
+ keyPath : KeyPath < K > ,
130
+ notSetValue : NSV | UpdaterFunction < K , C > | undefined ,
131
+ updater ?: UpdaterFunctionWithNSV < K , C , NSV >
48
132
) : C {
49
133
if ( ! updater ) {
50
134
// handle the fact that `notSetValue` is optional here, in that case `updater` is the updater function
51
- updater = notSetValue as UpdaterFunction ;
135
+ // @ts -expect-error updater is a function here
136
+ updater = notSetValue as UpdaterFunction < K , C > ;
52
137
notSetValue = undefined ;
53
138
}
54
139
const updatedValue = updateInDeeply (
55
140
isImmutable ( collection ) ,
141
+ // @ts -expect-error type issues with Record and mixed types
56
142
collection ,
57
143
coerceKeyPath ( keyPath ) ,
58
144
0 ,
@@ -63,17 +149,23 @@ export function updateIn<C extends UpdateTypeParameters[0]>(
63
149
return updatedValue === NOT_SET ? notSetValue : updatedValue ;
64
150
}
65
151
66
- function updateInDeeply < C extends UpdateTypeParameters [ 0 ] > (
152
+ function updateInDeeply <
153
+ K extends PropertyKey ,
154
+ TProps extends object ,
155
+ C extends PossibleCollection < unknown , unknown , TProps > ,
156
+ NSV ,
157
+ > (
67
158
inImmutable : boolean ,
68
159
existing : C ,
69
- keyPath : ArrayLike < UpdateTypeParameters [ 1 ] > ,
160
+ keyPath : Array < K > ,
70
161
i : number ,
71
- notSetValue : UpdateTypeParameters [ 2 ] ,
72
- updater : UpdateTypeParameters [ 3 ]
162
+ notSetValue : NSV | undefined ,
163
+ updater : UpdaterFunctionWithNSV < K , C , NSV > | UpdaterFunction < K , C >
73
164
) : C {
74
165
const wasNotSet = existing === NOT_SET ;
75
166
if ( i === keyPath . length ) {
76
167
const existingValue = wasNotSet ? notSetValue : existing ;
168
+ // @ts -expect-error mixed type with optional value
77
169
const newValue = updater ( existingValue ) ;
78
170
// @ts -expect-error mixed type
79
171
return newValue === existingValue ? existing : newValue ;
0 commit comments