merge-anything 5.1.7 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare function concatArrays<T>(originVal: unknown, newVal: T): T;
@@ -0,0 +1,8 @@
1
+ import { isArray } from 'is-what';
2
+ export function concatArrays(originVal, newVal) {
3
+ if (isArray(originVal) && isArray(newVal)) {
4
+ // concat logic
5
+ return originVal.concat(newVal);
6
+ }
7
+ return newVal; // always return newVal as fallback!!
8
+ }
package/dist/index.d.ts CHANGED
@@ -1,416 +1,2 @@
1
- /**
2
- * Get the keys of `O` that are optional
3
- * @param O
4
- * @returns [[Key]]
5
- * @example
6
- * ```ts
7
- * ```
8
- */
9
- type OptionalKeys<O extends object> = O extends unknown ? {
10
- [K in keyof O]-?: {} extends Pick<O, K> ? K : never;
11
- }[keyof O] : never;
12
- /**
13
- * Get the keys of `O` that are required
14
- * @param O
15
- * @returns [[Key]]
16
- * @example
17
- * ```ts
18
- * ```
19
- */
20
- type RequiredKeys<O extends object> = O extends unknown ? {
21
- [K in keyof O]-?: {} extends Pick<O, K> ? never : K;
22
- }[keyof O] : never;
23
- type MergeObjectDeeply<O extends Record<string | number | symbol, unknown>, O1 extends Record<string | number | symbol, unknown>> = {
24
- [K in keyof (O & O1)]: K extends RequiredKeys<O1> ? MergeObjectsOrReturnFallback<O[K], O1[K], O1[K]> : K extends OptionalKeys<O1> ? K extends OptionalKeys<O> ? MergeObjectsOrReturnFallback<Exclude<O[K], undefined>, Exclude<O1[K], undefined>, Exclude<O[K], undefined> | Exclude<O1[K], undefined>> : K extends RequiredKeys<O> ? Exclude<O1[K], undefined> extends O[K] ? O[K] : MergeObjectsOrReturnFallback<O[K], Exclude<O1[K], undefined>, O[K] | Exclude<O1[K], undefined>> : O1[K] : O[K];
25
- };
26
- type MergeObjectsOrReturnFallback<O, O1, Fallback> = O extends Record<string | number | symbol, unknown> ? O1 extends Record<string | number | symbol, unknown> ? MergeObjectDeeply<O, O1> : Fallback : Fallback;
27
- /**
28
- * Accurately merge the fields of `O` with the ones of `O1`. It is
29
- * equivalent to the spread operator in JavaScript. [[Union]]s and [[Optional]]
30
- * fields will be handled gracefully.
31
- *
32
- * (⚠️ needs `--strictNullChecks` enabled)
33
- * @param O to complete
34
- * @param O1 to copy from
35
- * @returns [[Object]]
36
- * @example
37
- * ```ts
38
- * import { PrettyPrint } from './PrettyPrint'
39
- *
40
- * type A1 = { a: number; b?: number; d?: number; e?: number; x: string; y?: number; z: string; } // prettier-ignore
41
- * type A2 = { a?: number; c?: number; d?: number; e: number; x: number | undefined; y?: string; z?: number; } // prettier-ignore
42
- *
43
- * type Result = PrettyPrint<MergeDeep<A1, A2>>
44
- * {
45
- * a: number;
46
- * b?: number | undefined;
47
- * c?: number | undefined;
48
- * d?: number | undefined;
49
- * e: number;
50
- * x: number | undefined;
51
- * y?: string | number | undefined;
52
- * z: string | number;
53
- * }
54
- * ```
55
- */
56
- type MergeDeep<O extends Record<string | number | symbol, unknown>, O1 extends Record<string | number | symbol, unknown>> = O extends unknown ? (O1 extends unknown ? MergeObjectDeeply<O, O1> : never) : never;
57
-
58
- /**
59
- * An entry of `IterationMap`
60
- */
61
- type Iteration = [
62
- value: number,
63
- sign: '-' | '0' | '+',
64
- prev: keyof IterationMap,
65
- next: keyof IterationMap,
66
- oppo: keyof IterationMap
67
- ];
68
- type IterationMap = {
69
- '__': [number, '-' | '0' | '+', '__', '__', '__'];
70
- '-100': [-100, '-', '__', '-99', '100'];
71
- '-99': [-99, '-', '-100', '-98', '99'];
72
- '-98': [-98, '-', '-99', '-97', '98'];
73
- '-97': [-97, '-', '-98', '-96', '97'];
74
- '-96': [-96, '-', '-97', '-95', '96'];
75
- '-95': [-95, '-', '-96', '-94', '95'];
76
- '-94': [-94, '-', '-95', '-93', '94'];
77
- '-93': [-93, '-', '-94', '-92', '93'];
78
- '-92': [-92, '-', '-93', '-91', '92'];
79
- '-91': [-91, '-', '-92', '-90', '91'];
80
- '-90': [-90, '-', '-91', '-89', '90'];
81
- '-89': [-89, '-', '-90', '-88', '89'];
82
- '-88': [-88, '-', '-89', '-87', '88'];
83
- '-87': [-87, '-', '-88', '-86', '87'];
84
- '-86': [-86, '-', '-87', '-85', '86'];
85
- '-85': [-85, '-', '-86', '-84', '85'];
86
- '-84': [-84, '-', '-85', '-83', '84'];
87
- '-83': [-83, '-', '-84', '-82', '83'];
88
- '-82': [-82, '-', '-83', '-81', '82'];
89
- '-81': [-81, '-', '-82', '-80', '81'];
90
- '-80': [-80, '-', '-81', '-79', '80'];
91
- '-79': [-79, '-', '-80', '-78', '79'];
92
- '-78': [-78, '-', '-79', '-77', '78'];
93
- '-77': [-77, '-', '-78', '-76', '77'];
94
- '-76': [-76, '-', '-77', '-75', '76'];
95
- '-75': [-75, '-', '-76', '-74', '75'];
96
- '-74': [-74, '-', '-75', '-73', '74'];
97
- '-73': [-73, '-', '-74', '-72', '73'];
98
- '-72': [-72, '-', '-73', '-71', '72'];
99
- '-71': [-71, '-', '-72', '-70', '71'];
100
- '-70': [-70, '-', '-71', '-69', '70'];
101
- '-69': [-69, '-', '-70', '-68', '69'];
102
- '-68': [-68, '-', '-69', '-67', '68'];
103
- '-67': [-67, '-', '-68', '-66', '67'];
104
- '-66': [-66, '-', '-67', '-65', '66'];
105
- '-65': [-65, '-', '-66', '-64', '65'];
106
- '-64': [-64, '-', '-65', '-63', '64'];
107
- '-63': [-63, '-', '-64', '-62', '63'];
108
- '-62': [-62, '-', '-63', '-61', '62'];
109
- '-61': [-61, '-', '-62', '-60', '61'];
110
- '-60': [-60, '-', '-61', '-59', '60'];
111
- '-59': [-59, '-', '-60', '-58', '59'];
112
- '-58': [-58, '-', '-59', '-57', '58'];
113
- '-57': [-57, '-', '-58', '-56', '57'];
114
- '-56': [-56, '-', '-57', '-55', '56'];
115
- '-55': [-55, '-', '-56', '-54', '55'];
116
- '-54': [-54, '-', '-55', '-53', '54'];
117
- '-53': [-53, '-', '-54', '-52', '53'];
118
- '-52': [-52, '-', '-53', '-51', '52'];
119
- '-51': [-51, '-', '-52', '-50', '51'];
120
- '-50': [-50, '-', '-51', '-49', '50'];
121
- '-49': [-49, '-', '-50', '-48', '49'];
122
- '-48': [-48, '-', '-49', '-47', '48'];
123
- '-47': [-47, '-', '-48', '-46', '47'];
124
- '-46': [-46, '-', '-47', '-45', '46'];
125
- '-45': [-45, '-', '-46', '-44', '45'];
126
- '-44': [-44, '-', '-45', '-43', '44'];
127
- '-43': [-43, '-', '-44', '-42', '43'];
128
- '-42': [-42, '-', '-43', '-41', '42'];
129
- '-41': [-41, '-', '-42', '-40', '41'];
130
- '-40': [-40, '-', '-41', '-39', '40'];
131
- '-39': [-39, '-', '-40', '-38', '39'];
132
- '-38': [-38, '-', '-39', '-37', '38'];
133
- '-37': [-37, '-', '-38', '-36', '37'];
134
- '-36': [-36, '-', '-37', '-35', '36'];
135
- '-35': [-35, '-', '-36', '-34', '35'];
136
- '-34': [-34, '-', '-35', '-33', '34'];
137
- '-33': [-33, '-', '-34', '-32', '33'];
138
- '-32': [-32, '-', '-33', '-31', '32'];
139
- '-31': [-31, '-', '-32', '-30', '31'];
140
- '-30': [-30, '-', '-31', '-29', '30'];
141
- '-29': [-29, '-', '-30', '-28', '29'];
142
- '-28': [-28, '-', '-29', '-27', '28'];
143
- '-27': [-27, '-', '-28', '-26', '27'];
144
- '-26': [-26, '-', '-27', '-25', '26'];
145
- '-25': [-25, '-', '-26', '-24', '25'];
146
- '-24': [-24, '-', '-25', '-23', '24'];
147
- '-23': [-23, '-', '-24', '-22', '23'];
148
- '-22': [-22, '-', '-23', '-21', '22'];
149
- '-21': [-21, '-', '-22', '-20', '21'];
150
- '-20': [-20, '-', '-21', '-19', '20'];
151
- '-19': [-19, '-', '-20', '-18', '19'];
152
- '-18': [-18, '-', '-19', '-17', '18'];
153
- '-17': [-17, '-', '-18', '-16', '17'];
154
- '-16': [-16, '-', '-17', '-15', '16'];
155
- '-15': [-15, '-', '-16', '-14', '15'];
156
- '-14': [-14, '-', '-15', '-13', '14'];
157
- '-13': [-13, '-', '-14', '-12', '13'];
158
- '-12': [-12, '-', '-13', '-11', '12'];
159
- '-11': [-11, '-', '-12', '-10', '11'];
160
- '-10': [-10, '-', '-11', '-9', '10'];
161
- '-9': [-9, '-', '-10', '-8', '9'];
162
- '-8': [-8, '-', '-9', '-7', '8'];
163
- '-7': [-7, '-', '-8', '-6', '7'];
164
- '-6': [-6, '-', '-7', '-5', '6'];
165
- '-5': [-5, '-', '-6', '-4', '5'];
166
- '-4': [-4, '-', '-5', '-3', '4'];
167
- '-3': [-3, '-', '-4', '-2', '3'];
168
- '-2': [-2, '-', '-3', '-1', '2'];
169
- '-1': [-1, '-', '-2', '0', '1'];
170
- '0': [0, '0', '-1', '1', '0'];
171
- '1': [1, '+', '0', '2', '-1'];
172
- '2': [2, '+', '1', '3', '-2'];
173
- '3': [3, '+', '2', '4', '-3'];
174
- '4': [4, '+', '3', '5', '-4'];
175
- '5': [5, '+', '4', '6', '-5'];
176
- '6': [6, '+', '5', '7', '-6'];
177
- '7': [7, '+', '6', '8', '-7'];
178
- '8': [8, '+', '7', '9', '-8'];
179
- '9': [9, '+', '8', '10', '-9'];
180
- '10': [10, '+', '9', '11', '-10'];
181
- '11': [11, '+', '10', '12', '-11'];
182
- '12': [12, '+', '11', '13', '-12'];
183
- '13': [13, '+', '12', '14', '-13'];
184
- '14': [14, '+', '13', '15', '-14'];
185
- '15': [15, '+', '14', '16', '-15'];
186
- '16': [16, '+', '15', '17', '-16'];
187
- '17': [17, '+', '16', '18', '-17'];
188
- '18': [18, '+', '17', '19', '-18'];
189
- '19': [19, '+', '18', '20', '-19'];
190
- '20': [20, '+', '19', '21', '-20'];
191
- '21': [21, '+', '20', '22', '-21'];
192
- '22': [22, '+', '21', '23', '-22'];
193
- '23': [23, '+', '22', '24', '-23'];
194
- '24': [24, '+', '23', '25', '-24'];
195
- '25': [25, '+', '24', '26', '-25'];
196
- '26': [26, '+', '25', '27', '-26'];
197
- '27': [27, '+', '26', '28', '-27'];
198
- '28': [28, '+', '27', '29', '-28'];
199
- '29': [29, '+', '28', '30', '-29'];
200
- '30': [30, '+', '29', '31', '-30'];
201
- '31': [31, '+', '30', '32', '-31'];
202
- '32': [32, '+', '31', '33', '-32'];
203
- '33': [33, '+', '32', '34', '-33'];
204
- '34': [34, '+', '33', '35', '-34'];
205
- '35': [35, '+', '34', '36', '-35'];
206
- '36': [36, '+', '35', '37', '-36'];
207
- '37': [37, '+', '36', '38', '-37'];
208
- '38': [38, '+', '37', '39', '-38'];
209
- '39': [39, '+', '38', '40', '-39'];
210
- '40': [40, '+', '39', '41', '-40'];
211
- '41': [41, '+', '40', '42', '-41'];
212
- '42': [42, '+', '41', '43', '-42'];
213
- '43': [43, '+', '42', '44', '-43'];
214
- '44': [44, '+', '43', '45', '-44'];
215
- '45': [45, '+', '44', '46', '-45'];
216
- '46': [46, '+', '45', '47', '-46'];
217
- '47': [47, '+', '46', '48', '-47'];
218
- '48': [48, '+', '47', '49', '-48'];
219
- '49': [49, '+', '48', '50', '-49'];
220
- '50': [50, '+', '49', '51', '-50'];
221
- '51': [51, '+', '50', '52', '-51'];
222
- '52': [52, '+', '51', '53', '-52'];
223
- '53': [53, '+', '52', '54', '-53'];
224
- '54': [54, '+', '53', '55', '-54'];
225
- '55': [55, '+', '54', '56', '-55'];
226
- '56': [56, '+', '55', '57', '-56'];
227
- '57': [57, '+', '56', '58', '-57'];
228
- '58': [58, '+', '57', '59', '-58'];
229
- '59': [59, '+', '58', '60', '-59'];
230
- '60': [60, '+', '59', '61', '-60'];
231
- '61': [61, '+', '60', '62', '-61'];
232
- '62': [62, '+', '61', '63', '-62'];
233
- '63': [63, '+', '62', '64', '-63'];
234
- '64': [64, '+', '63', '65', '-64'];
235
- '65': [65, '+', '64', '66', '-65'];
236
- '66': [66, '+', '65', '67', '-66'];
237
- '67': [67, '+', '66', '68', '-67'];
238
- '68': [68, '+', '67', '69', '-68'];
239
- '69': [69, '+', '68', '70', '-69'];
240
- '70': [70, '+', '69', '71', '-70'];
241
- '71': [71, '+', '70', '72', '-71'];
242
- '72': [72, '+', '71', '73', '-72'];
243
- '73': [73, '+', '72', '74', '-73'];
244
- '74': [74, '+', '73', '75', '-74'];
245
- '75': [75, '+', '74', '76', '-75'];
246
- '76': [76, '+', '75', '77', '-76'];
247
- '77': [77, '+', '76', '78', '-77'];
248
- '78': [78, '+', '77', '79', '-78'];
249
- '79': [79, '+', '78', '80', '-79'];
250
- '80': [80, '+', '79', '81', '-80'];
251
- '81': [81, '+', '80', '82', '-81'];
252
- '82': [82, '+', '81', '83', '-82'];
253
- '83': [83, '+', '82', '84', '-83'];
254
- '84': [84, '+', '83', '85', '-84'];
255
- '85': [85, '+', '84', '86', '-85'];
256
- '86': [86, '+', '85', '87', '-86'];
257
- '87': [87, '+', '86', '88', '-87'];
258
- '88': [88, '+', '87', '89', '-88'];
259
- '89': [89, '+', '88', '90', '-89'];
260
- '90': [90, '+', '89', '91', '-90'];
261
- '91': [91, '+', '90', '92', '-91'];
262
- '92': [92, '+', '91', '93', '-92'];
263
- '93': [93, '+', '92', '94', '-93'];
264
- '94': [94, '+', '93', '95', '-94'];
265
- '95': [95, '+', '94', '96', '-95'];
266
- '96': [96, '+', '95', '97', '-96'];
267
- '97': [97, '+', '96', '98', '-97'];
268
- '98': [98, '+', '97', '99', '-98'];
269
- '99': [99, '+', '98', '100', '-99'];
270
- '100': [100, '+', '99', '__', '-100'];
271
- };
272
- /**
273
- * Transform a number into an [[Iteration]]
274
- * (to use [[Prev]], [[Next]], & [[Pos]])
275
- * @param N to transform
276
- * @returns [[Iteration]]
277
- * @example
278
- * ```ts
279
- * type i = IterationOf<0> // ["-1", "1", "0", 0, "0"]
280
- *
281
- * type next = Next<i> // ["0", "2", "1", 1, "+"]
282
- * type prev = Prev<i> // ["-2", "0", "-1", -1, "-"]
283
- *
284
- * type nnext = Pos<next> // +1
285
- * type nprev = Pos<prev> // -1
286
- * ```
287
- */
288
- type IterationOf<N extends number> = `${N}` extends keyof IterationMap ? IterationMap[`${N}`] : IterationMap['__'];
289
- /**
290
- * Get the position of `I` (**number**)
291
- * @param I to query
292
- * @returns `number`
293
- * @example
294
- * ```ts
295
- * type i = IterationOf<'20'>
296
- *
297
- * type test0 = Pos<i> // 20
298
- * type test1 = Pos<Next<i>> // 21
299
- * ```
300
- */
301
- type Pos<I extends Iteration> = I[0];
302
- /**
303
- * Move `I`'s position forward
304
- * @param I to move
305
- * @returns [[Iteration]]
306
- * @example
307
- * ```ts
308
- * type i = IterationOf<'20'>
309
- *
310
- * type test0 = Pos<i> // 20
311
- * type test1 = Pos<Next<i>> // 21
312
- * ```
313
- */
314
- type Next<I extends Iteration> = IterationMap[I[3]];
315
-
316
- /**
317
- * A [[List]]
318
- * @param T its type
319
- * @returns [[List]]
320
- * @example
321
- * ```ts
322
- * type list0 = [1, 2, 3]
323
- * type list1 = number[]
324
- * ```
325
- */
326
- type List<T = any> = readonly T[];
327
- /**
328
- * Get the length of `L`
329
- * @param L to get length
330
- * @returns [[String]] or `number`
331
- * @example
332
- * ```ts
333
- * ```
334
- */
335
- type Length<L extends List> = L['length'];
336
- /**
337
- * Return the last item out of a [[List]]
338
- * @param L
339
- * @returns [[List]]
340
- * @example
341
- * ```ts
342
- * ```
343
- */
344
- type Pop<L extends List> = L extends readonly [] ? never : L extends [...unknown[], infer Last] ? Last : L extends (infer T)[] ? T : never;
345
-
346
- /**
347
- * Ask TS to re-check that `A1` extends `A2`.
348
- * And if it fails, `A2` will be enforced anyway.
349
- * Can also be used to add constraints on parameters.
350
- * @param A1 to check against
351
- * @param A2 to cast to
352
- * @returns `A1 | A2`
353
- * @example
354
- * ```ts
355
- * type test0 = Cast<'42', string> // '42'
356
- * type test1 = Cast<'42', number> // number
357
- * ```
358
- */
359
- type Cast<A1, A2> = A1 extends A2 ? A1 : A2;
360
- /**
361
- * Check whether `A1` is part of `A2` or not. The difference with
362
- * `extends` is that it forces a [[Boolean]] return.
363
- * @param A1
364
- * @param A2
365
- * @returns [[Boolean]]
366
- * @example
367
- * ```ts
368
- * type test0 = Extends<'a' | 'b', 'b'> // Boolean
369
- * type test1 = Extends<'a', 'a' | 'b'> // True
370
- *
371
- * type test2 = Extends<{a: string}, {a: any}> // True
372
- * type test3 = Extends<{a: any}, {a: any, b: any}> // False
373
- *
374
- * type test4 = Extends<never, never> // False
375
- * /// Nothing cannot extend nothing, use `Equals`
376
- * ```
377
- */
378
- type Extends<A1, A2> = [A1] extends [never] ? 0 : A1 extends A2 ? 1 : 0;
379
- type __Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>, I extends Iteration = IterationOf<0>> = Extends<Pos<I>, Length<Os>> extends 1 ? O : __Assign<MergeDeep<O, Os[Pos<I>]>, Os, Next<I>>;
380
- type _Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = __Assign<O, Os> extends infer X ? Cast<X, Record<string | number | symbol, unknown>> : never;
381
- /**
382
- * Assign a list of [[Object]] into `O` with [[MergeDeep]]. Merges from right to
383
- * left, first items get overridden by the next ones (last-in overrides).
384
- * @param O to assign to
385
- * @param Os to assign
386
- * @returns [[Object]]
387
- * @example
388
- * ```ts
389
- * ```
390
- */
391
- type Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = O extends unknown ? (Os extends unknown ? _Assign<O, Os> : never) : never;
392
-
393
- type Has<U, U1> = [U1] extends [U] ? 1 : 0;
394
- type If<B extends 0 | 1, Then, Else = never> = B extends 1 ? Then : Else;
395
- type PrettyPrint<A, Seen = never> = If<Has<Seen, A>, A, A extends Record<string | number | symbol, unknown> ? {
396
- [K in keyof A]: PrettyPrint<A[K], A | Seen>;
397
- } & unknown : A>;
398
-
399
- /**
400
- * The return type of `merge()`. It reflects the type that is returned by JavaScript.
401
- *
402
- * This TS Utility can be used as standalone as well
403
- */
404
- type Merge<T, Ts extends unknown[]> = T extends Record<string | number | symbol, unknown> ? Ts extends Record<string | number | symbol, unknown>[] ? PrettyPrint<Assign<T, Ts>> : Pop<Ts> : Pop<Ts>;
405
- /**
406
- * Merge anything recursively.
407
- * Objects get merged, special objects (classes etc.) are re-assigned "as is".
408
- * Basic types overwrite objects or other basic types.
409
- */
410
- declare function merge<T, Tn extends unknown[]>(object: T, ...otherObjects: Tn): Merge<T, Tn>;
411
- declare function mergeAndCompare<T, Tn extends unknown[]>(compareFn: (prop1: any, prop2: any, propName: string | symbol) => any, object: T, ...otherObjects: Tn): Merge<T, Tn>;
412
- declare function mergeAndConcat<T, Tn extends unknown[]>(object: T, ...otherObjects: Tn): Merge<T, Tn>;
413
-
414
- declare function concatArrays(originVal: any, newVal: any): any | any[];
415
-
416
- export { Merge, concatArrays, merge, mergeAndCompare, mergeAndConcat };
1
+ export * from './extensions.js';
2
+ export * from './merge.js';
package/dist/index.js CHANGED
@@ -1,78 +1,2 @@
1
- import { isArray, isPlainObject, isSymbol } from 'is-what';
2
-
3
- function concatArrays(originVal, newVal) {
4
- if (isArray(originVal) && isArray(newVal)) {
5
- return originVal.concat(newVal);
6
- }
7
- return newVal;
8
- }
9
-
10
- function assignProp(carry, key, newVal, originalObject) {
11
- const propType = {}.propertyIsEnumerable.call(originalObject, key) ? "enumerable" : "nonenumerable";
12
- if (propType === "enumerable")
13
- carry[key] = newVal;
14
- if (propType === "nonenumerable") {
15
- Object.defineProperty(carry, key, {
16
- value: newVal,
17
- enumerable: false,
18
- writable: true,
19
- configurable: true
20
- });
21
- }
22
- }
23
- function mergeRecursively(origin, newComer, compareFn) {
24
- if (!isPlainObject(newComer))
25
- return newComer;
26
- let newObject = {};
27
- if (isPlainObject(origin)) {
28
- const props2 = Object.getOwnPropertyNames(origin);
29
- const symbols2 = Object.getOwnPropertySymbols(origin);
30
- newObject = [...props2, ...symbols2].reduce((carry, key) => {
31
- const targetVal = origin[key];
32
- if (!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key) || isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key)) {
33
- assignProp(
34
- carry,
35
- key,
36
- targetVal,
37
- origin
38
- );
39
- }
40
- return carry;
41
- }, {});
42
- }
43
- const props = Object.getOwnPropertyNames(newComer);
44
- const symbols = Object.getOwnPropertySymbols(newComer);
45
- const result = [...props, ...symbols].reduce((carry, key) => {
46
- let newVal = newComer[key];
47
- const targetVal = isPlainObject(origin) ? origin[key] : void 0;
48
- if (targetVal !== void 0 && isPlainObject(newVal)) {
49
- newVal = mergeRecursively(targetVal, newVal, compareFn);
50
- }
51
- const propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
52
- assignProp(
53
- carry,
54
- key,
55
- propToAssign,
56
- newComer
57
- );
58
- return carry;
59
- }, newObject);
60
- return result;
61
- }
62
- function merge(object, ...otherObjects) {
63
- return otherObjects.reduce((result, newComer) => {
64
- return mergeRecursively(result, newComer);
65
- }, object);
66
- }
67
- function mergeAndCompare(compareFn, object, ...otherObjects) {
68
- return otherObjects.reduce((result, newComer) => {
69
- return mergeRecursively(result, newComer, compareFn);
70
- }, object);
71
- }
72
- function mergeAndConcat(object, ...otherObjects) {
73
- return otherObjects.reduce((result, newComer) => {
74
- return mergeRecursively(result, newComer, concatArrays);
75
- }, object);
76
- }
77
-
78
- export { concatArrays, merge, mergeAndCompare, mergeAndConcat };
1
+ export * from './extensions.js';
2
+ export * from './merge.js';
@@ -0,0 +1,17 @@
1
+ import type { Assign } from './typeUtils/Assign.js';
2
+ import type { Pop } from './typeUtils/List.js';
3
+ import type { PrettyPrint } from './typeUtils/PrettyPrint.js';
4
+ /**
5
+ * The return type of `merge()`. It reflects the type that is returned by JavaScript.
6
+ *
7
+ * This TS Utility can be used as standalone as well
8
+ */
9
+ export type Merge<T, Ts extends unknown[]> = T extends Record<string | number | symbol, unknown> ? Ts extends Record<string | number | symbol, unknown>[] ? PrettyPrint<Assign<T, Ts>> : Pop<Ts> : Pop<Ts>;
10
+ /**
11
+ * Merge anything recursively.
12
+ * Objects get merged, special objects (classes etc.) are re-assigned "as is".
13
+ * Basic types overwrite objects or other basic types.
14
+ */
15
+ export declare function merge<T, Tn extends unknown[]>(object: T, ...otherObjects: Tn): Merge<T, Tn>;
16
+ export declare function mergeAndCompare<T, Tn extends unknown[]>(compareFn: (prop1: unknown, prop2: unknown, propName: string | symbol) => any, object: T, ...otherObjects: Tn): Merge<T, Tn>;
17
+ export declare function mergeAndConcat<T, Tn extends unknown[]>(object: T, ...otherObjects: Tn): Merge<T, Tn>;
package/dist/merge.js ADDED
@@ -0,0 +1,107 @@
1
+ import { isPlainObject, isSymbol } from 'is-what';
2
+ import { concatArrays } from './extensions.js';
3
+ function assignProp(carry, key, newVal, originalObject) {
4
+ const propType = {}.propertyIsEnumerable.call(originalObject, key)
5
+ ? 'enumerable'
6
+ : 'nonenumerable';
7
+ if (propType === 'enumerable')
8
+ carry[key] = newVal;
9
+ if (propType === 'nonenumerable') {
10
+ Object.defineProperty(carry, key, {
11
+ value: newVal,
12
+ enumerable: false,
13
+ writable: true,
14
+ configurable: true,
15
+ });
16
+ }
17
+ }
18
+ function mergeRecursively(origin, newComer, compareFn) {
19
+ // always return newComer if its not an object
20
+ if (!isPlainObject(newComer))
21
+ return newComer;
22
+ // define newObject to merge all values upon
23
+ let newObject = {};
24
+ if (isPlainObject(origin)) {
25
+ const props = Object.getOwnPropertyNames(origin);
26
+ const symbols = Object.getOwnPropertySymbols(origin);
27
+ newObject = [...props, ...symbols].reduce((carry, key) => {
28
+ const targetVal = origin[key];
29
+ if ((!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
30
+ (isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) {
31
+ assignProp(carry, key, targetVal, origin);
32
+ }
33
+ return carry;
34
+ }, {});
35
+ }
36
+ // newObject has all properties that newComer hasn't
37
+ const props = Object.getOwnPropertyNames(newComer);
38
+ const symbols = Object.getOwnPropertySymbols(newComer);
39
+ const result = [...props, ...symbols].reduce((carry, key) => {
40
+ // re-define the origin and newComer as targetVal and newVal
41
+ let newVal = newComer[key];
42
+ const targetVal = isPlainObject(origin) ? origin[key] : undefined;
43
+ // When newVal is an object do the merge recursively
44
+ if (targetVal !== undefined && isPlainObject(newVal)) {
45
+ newVal = mergeRecursively(targetVal, newVal, compareFn);
46
+ }
47
+ const propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
48
+ assignProp(carry, key, propToAssign, newComer);
49
+ return carry;
50
+ }, newObject);
51
+ return result;
52
+ }
53
+ /**
54
+ * Merge anything recursively.
55
+ * Objects get merged, special objects (classes etc.) are re-assigned "as is".
56
+ * Basic types overwrite objects or other basic types.
57
+ */
58
+ export function merge(object, ...otherObjects) {
59
+ return otherObjects.reduce((result, newComer) => {
60
+ return mergeRecursively(result, newComer);
61
+ }, object);
62
+ }
63
+ export function mergeAndCompare(compareFn, object, ...otherObjects) {
64
+ return otherObjects.reduce((result, newComer) => {
65
+ return mergeRecursively(result, newComer, compareFn);
66
+ }, object);
67
+ }
68
+ export function mergeAndConcat(object, ...otherObjects) {
69
+ return otherObjects.reduce((result, newComer) => {
70
+ return mergeRecursively(result, newComer, concatArrays);
71
+ }, object);
72
+ }
73
+ // import { Timestamp } from '../test/Timestamp'
74
+ // type T1 = { date: Timestamp }
75
+ // type T2 = [{ b: string[] }, { b: number[] }, { date: Timestamp }]
76
+ // type TestT = Merge<T1, T2>
77
+ // type A1 = { arr: string[] }
78
+ // type A2 = { arr: number[] }
79
+ // type A3 = { arr: boolean[] }
80
+ // type TestA = Merge<A1, [A2, A3]>
81
+ // interface I1 {
82
+ // date: Timestamp
83
+ // }
84
+ // interface I2 {
85
+ // date: Timestamp
86
+ // }
87
+ // const _a: I2 = { date: '' } as unknown as I2
88
+ // type TestI = Merge<I1, [I2]>
89
+ // // ReturnType<(typeof merge)<I1, I2>>
90
+ // const a = merge(_a, [_a])
91
+ // interface Arguments extends Record<string | number | symbol, unknown> {
92
+ // key: string;
93
+ // }
94
+ // const aa1: Arguments = { key: "value1" }
95
+ // const aa2: Arguments = { key: "value2" }
96
+ // const aa = merge(a1, a2);
97
+ // interface Barguments {
98
+ // key: string
99
+ // }
100
+ // const ba1: Barguments = { key: 'value1' }
101
+ // const ba2: Barguments = { key: 'value2' }
102
+ // const ba = merge(ba1, ba2)
103
+ // interface Carguments {
104
+ // key: string
105
+ // }
106
+ // const ca = merge<Carguments, Carguments[]>({ key: 'value1' }, { key: 'value2' })
107
+ // type P = Pop<Carguments[]>
@@ -0,0 +1,50 @@
1
+ import type { Iteration, IterationOf, Next, Pos } from './Iteration.js';
2
+ import type { Length, List } from './List.js';
3
+ import type { MergeDeep } from './MergeDeep.js';
4
+ /**
5
+ * Ask TS to re-check that `A1` extends `A2`.
6
+ * And if it fails, `A2` will be enforced anyway.
7
+ * Can also be used to add constraints on parameters.
8
+ * @param A1 to check against
9
+ * @param A2 to cast to
10
+ * @returns `A1 | A2`
11
+ * @example
12
+ * ```ts
13
+ * type test0 = Cast<'42', string> // '42'
14
+ * type test1 = Cast<'42', number> // number
15
+ * ```
16
+ */
17
+ type Cast<A1, A2> = A1 extends A2 ? A1 : A2;
18
+ /**
19
+ * Check whether `A1` is part of `A2` or not. The difference with
20
+ * `extends` is that it forces a [[Boolean]] return.
21
+ * @param A1
22
+ * @param A2
23
+ * @returns [[Boolean]]
24
+ * @example
25
+ * ```ts
26
+ * type test0 = Extends<'a' | 'b', 'b'> // Boolean
27
+ * type test1 = Extends<'a', 'a' | 'b'> // True
28
+ *
29
+ * type test2 = Extends<{a: string}, {a: any}> // True
30
+ * type test3 = Extends<{a: any}, {a: any, b: any}> // False
31
+ *
32
+ * type test4 = Extends<never, never> // False
33
+ * /// Nothing cannot extend nothing, use `Equals`
34
+ * ```
35
+ */
36
+ type Extends<A1, A2> = [A1] extends [never] ? 0 : A1 extends A2 ? 1 : 0;
37
+ type __Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>, I extends Iteration = IterationOf<0>> = Extends<Pos<I>, Length<Os>> extends 1 ? O : __Assign<MergeDeep<O, Os[Pos<I>]>, Os, Next<I>>;
38
+ type _Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = __Assign<O, Os> extends infer X ? Cast<X, Record<string | number | symbol, unknown>> : never;
39
+ /**
40
+ * Assign a list of [[Object]] into `O` with [[MergeDeep]]. Merges from right to
41
+ * left, first items get overridden by the next ones (last-in overrides).
42
+ * @param O to assign to
43
+ * @param Os to assign
44
+ * @returns [[Object]]
45
+ * @example
46
+ * ```ts
47
+ * ```
48
+ */
49
+ export type Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = O extends unknown ? (Os extends unknown ? _Assign<O, Os> : never) : never;
50
+ export {};
@@ -0,0 +1,12 @@
1
+ export {};
2
+ // type A1 = { arr: string[] }
3
+ // type A2 = { arr: number[] }
4
+ // type A3 = { arr: boolean[] }
5
+ // type TestA = Assign<A1, [A2, A3]>
6
+ // type B1 = { arr: number[] }
7
+ // type B2 = { arr?: number[] }
8
+ // type TestB = Assign<B1, [B2]>
9
+ // import { Timestamp } from '../../test/Timestamp'
10
+ // type T1 = { date: Timestamp }
11
+ // type T2 = { date: Timestamp }
12
+ // type TestT = Assign<T1, [T2]>
@@ -1,71 +1,14 @@
1
- /**
2
- * Get the keys of `O` that are optional
3
- * @param O
4
- * @returns [[Key]]
5
- * @example
6
- * ```ts
7
- * ```
8
- */
9
- type OptionalKeys<O extends object> = O extends unknown ? {
10
- [K in keyof O]-?: {} extends Pick<O, K> ? K : never;
11
- }[keyof O] : never;
12
- /**
13
- * Get the keys of `O` that are required
14
- * @param O
15
- * @returns [[Key]]
16
- * @example
17
- * ```ts
18
- * ```
19
- */
20
- type RequiredKeys<O extends object> = O extends unknown ? {
21
- [K in keyof O]-?: {} extends Pick<O, K> ? never : K;
22
- }[keyof O] : never;
23
- type MergeObjectDeeply<O extends Record<string | number | symbol, unknown>, O1 extends Record<string | number | symbol, unknown>> = {
24
- [K in keyof (O & O1)]: K extends RequiredKeys<O1> ? MergeObjectsOrReturnFallback<O[K], O1[K], O1[K]> : K extends OptionalKeys<O1> ? K extends OptionalKeys<O> ? MergeObjectsOrReturnFallback<Exclude<O[K], undefined>, Exclude<O1[K], undefined>, Exclude<O[K], undefined> | Exclude<O1[K], undefined>> : K extends RequiredKeys<O> ? Exclude<O1[K], undefined> extends O[K] ? O[K] : MergeObjectsOrReturnFallback<O[K], Exclude<O1[K], undefined>, O[K] | Exclude<O1[K], undefined>> : O1[K] : O[K];
25
- };
26
- type MergeObjectsOrReturnFallback<O, O1, Fallback> = O extends Record<string | number | symbol, unknown> ? O1 extends Record<string | number | symbol, unknown> ? MergeObjectDeeply<O, O1> : Fallback : Fallback;
27
- /**
28
- * Accurately merge the fields of `O` with the ones of `O1`. It is
29
- * equivalent to the spread operator in JavaScript. [[Union]]s and [[Optional]]
30
- * fields will be handled gracefully.
31
- *
32
- * (⚠️ needs `--strictNullChecks` enabled)
33
- * @param O to complete
34
- * @param O1 to copy from
35
- * @returns [[Object]]
36
- * @example
37
- * ```ts
38
- * import { PrettyPrint } from './PrettyPrint'
39
- *
40
- * type A1 = { a: number; b?: number; d?: number; e?: number; x: string; y?: number; z: string; } // prettier-ignore
41
- * type A2 = { a?: number; c?: number; d?: number; e: number; x: number | undefined; y?: string; z?: number; } // prettier-ignore
42
- *
43
- * type Result = PrettyPrint<MergeDeep<A1, A2>>
44
- * {
45
- * a: number;
46
- * b?: number | undefined;
47
- * c?: number | undefined;
48
- * d?: number | undefined;
49
- * e: number;
50
- * x: number | undefined;
51
- * y?: string | number | undefined;
52
- * z: string | number;
53
- * }
54
- * ```
55
- */
56
- type MergeDeep<O extends Record<string | number | symbol, unknown>, O1 extends Record<string | number | symbol, unknown>> = O extends unknown ? (O1 extends unknown ? MergeObjectDeeply<O, O1> : never) : never;
57
-
58
1
  /**
59
2
  * An entry of `IterationMap`
60
3
  */
61
- type Iteration = [
4
+ export type Iteration = [
62
5
  value: number,
63
6
  sign: '-' | '0' | '+',
64
7
  prev: keyof IterationMap,
65
8
  next: keyof IterationMap,
66
9
  oppo: keyof IterationMap
67
10
  ];
68
- type IterationMap = {
11
+ export type IterationMap = {
69
12
  '__': [number, '-' | '0' | '+', '__', '__', '__'];
70
13
  '-100': [-100, '-', '__', '-99', '100'];
71
14
  '-99': [-99, '-', '-100', '-98', '99'];
@@ -285,7 +228,7 @@ type IterationMap = {
285
228
  * type nprev = Pos<prev> // -1
286
229
  * ```
287
230
  */
288
- type IterationOf<N extends number> = `${N}` extends keyof IterationMap ? IterationMap[`${N}`] : IterationMap['__'];
231
+ export type IterationOf<N extends number> = `${N}` extends keyof IterationMap ? IterationMap[`${N}`] : IterationMap['__'];
289
232
  /**
290
233
  * Get the position of `I` (**number**)
291
234
  * @param I to query
@@ -298,7 +241,7 @@ type IterationOf<N extends number> = `${N}` extends keyof IterationMap ? Iterati
298
241
  * type test1 = Pos<Next<i>> // 21
299
242
  * ```
300
243
  */
301
- type Pos<I extends Iteration> = I[0];
244
+ export type Pos<I extends Iteration> = I[0];
302
245
  /**
303
246
  * Move `I`'s position forward
304
247
  * @param I to move
@@ -311,106 +254,4 @@ type Pos<I extends Iteration> = I[0];
311
254
  * type test1 = Pos<Next<i>> // 21
312
255
  * ```
313
256
  */
314
- type Next<I extends Iteration> = IterationMap[I[3]];
315
-
316
- /**
317
- * A [[List]]
318
- * @param T its type
319
- * @returns [[List]]
320
- * @example
321
- * ```ts
322
- * type list0 = [1, 2, 3]
323
- * type list1 = number[]
324
- * ```
325
- */
326
- type List<T = any> = readonly T[];
327
- /**
328
- * Get the length of `L`
329
- * @param L to get length
330
- * @returns [[String]] or `number`
331
- * @example
332
- * ```ts
333
- * ```
334
- */
335
- type Length<L extends List> = L['length'];
336
- /**
337
- * Return the last item out of a [[List]]
338
- * @param L
339
- * @returns [[List]]
340
- * @example
341
- * ```ts
342
- * ```
343
- */
344
- type Pop<L extends List> = L extends readonly [] ? never : L extends [...unknown[], infer Last] ? Last : L extends (infer T)[] ? T : never;
345
-
346
- /**
347
- * Ask TS to re-check that `A1` extends `A2`.
348
- * And if it fails, `A2` will be enforced anyway.
349
- * Can also be used to add constraints on parameters.
350
- * @param A1 to check against
351
- * @param A2 to cast to
352
- * @returns `A1 | A2`
353
- * @example
354
- * ```ts
355
- * type test0 = Cast<'42', string> // '42'
356
- * type test1 = Cast<'42', number> // number
357
- * ```
358
- */
359
- type Cast<A1, A2> = A1 extends A2 ? A1 : A2;
360
- /**
361
- * Check whether `A1` is part of `A2` or not. The difference with
362
- * `extends` is that it forces a [[Boolean]] return.
363
- * @param A1
364
- * @param A2
365
- * @returns [[Boolean]]
366
- * @example
367
- * ```ts
368
- * type test0 = Extends<'a' | 'b', 'b'> // Boolean
369
- * type test1 = Extends<'a', 'a' | 'b'> // True
370
- *
371
- * type test2 = Extends<{a: string}, {a: any}> // True
372
- * type test3 = Extends<{a: any}, {a: any, b: any}> // False
373
- *
374
- * type test4 = Extends<never, never> // False
375
- * /// Nothing cannot extend nothing, use `Equals`
376
- * ```
377
- */
378
- type Extends<A1, A2> = [A1] extends [never] ? 0 : A1 extends A2 ? 1 : 0;
379
- type __Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>, I extends Iteration = IterationOf<0>> = Extends<Pos<I>, Length<Os>> extends 1 ? O : __Assign<MergeDeep<O, Os[Pos<I>]>, Os, Next<I>>;
380
- type _Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = __Assign<O, Os> extends infer X ? Cast<X, Record<string | number | symbol, unknown>> : never;
381
- /**
382
- * Assign a list of [[Object]] into `O` with [[MergeDeep]]. Merges from right to
383
- * left, first items get overridden by the next ones (last-in overrides).
384
- * @param O to assign to
385
- * @param Os to assign
386
- * @returns [[Object]]
387
- * @example
388
- * ```ts
389
- * ```
390
- */
391
- type Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = O extends unknown ? (Os extends unknown ? _Assign<O, Os> : never) : never;
392
-
393
- type Has<U, U1> = [U1] extends [U] ? 1 : 0;
394
- type If<B extends 0 | 1, Then, Else = never> = B extends 1 ? Then : Else;
395
- type PrettyPrint<A, Seen = never> = If<Has<Seen, A>, A, A extends Record<string | number | symbol, unknown> ? {
396
- [K in keyof A]: PrettyPrint<A[K], A | Seen>;
397
- } & unknown : A>;
398
-
399
- /**
400
- * The return type of `merge()`. It reflects the type that is returned by JavaScript.
401
- *
402
- * This TS Utility can be used as standalone as well
403
- */
404
- type Merge<T, Ts extends unknown[]> = T extends Record<string | number | symbol, unknown> ? Ts extends Record<string | number | symbol, unknown>[] ? PrettyPrint<Assign<T, Ts>> : Pop<Ts> : Pop<Ts>;
405
- /**
406
- * Merge anything recursively.
407
- * Objects get merged, special objects (classes etc.) are re-assigned "as is".
408
- * Basic types overwrite objects or other basic types.
409
- */
410
- declare function merge<T, Tn extends unknown[]>(object: T, ...otherObjects: Tn): Merge<T, Tn>;
411
- declare function mergeAndCompare<T, Tn extends unknown[]>(compareFn: (prop1: any, prop2: any, propName: string | symbol) => any, object: T, ...otherObjects: Tn): Merge<T, Tn>;
412
- declare function mergeAndConcat<T, Tn extends unknown[]>(object: T, ...otherObjects: Tn): Merge<T, Tn>;
413
-
414
- declare function concatArrays(originVal: any, newVal: any): any | any[];
415
-
416
- export { Merge, concatArrays, merge, mergeAndCompare, mergeAndConcat };
257
+ export type Next<I extends Iteration> = IterationMap[I[3]];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * A [[List]]
3
+ * @param T its type
4
+ * @returns [[List]]
5
+ * @example
6
+ * ```ts
7
+ * type list0 = [1, 2, 3]
8
+ * type list1 = number[]
9
+ * ```
10
+ */
11
+ export type List<T = unknown> = readonly T[];
12
+ /**
13
+ * Get the length of `L`
14
+ * @param L to get length
15
+ * @returns [[String]] or `number`
16
+ * @example
17
+ * ```ts
18
+ * ```
19
+ */
20
+ export type Length<L extends List> = L['length'];
21
+ /**
22
+ * Return the last item out of a [[List]]
23
+ * @param L
24
+ * @returns [[List]]
25
+ * @example
26
+ * ```ts
27
+ * ```
28
+ */
29
+ export type Pop<L extends List> = L extends readonly [] ? never : L extends [...unknown[], infer Last] ? Last : L extends (infer T)[] ? T : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Get the keys of `O` that are optional
3
+ * @param O
4
+ * @returns [[Key]]
5
+ * @example
6
+ * ```ts
7
+ * ```
8
+ */
9
+ type OptionalKeys<O extends object> = O extends unknown ? {
10
+ [K in keyof O]-?: {} extends Pick<O, K> ? K : never;
11
+ }[keyof O] : never;
12
+ /**
13
+ * Get the keys of `O` that are required
14
+ * @param O
15
+ * @returns [[Key]]
16
+ * @example
17
+ * ```ts
18
+ * ```
19
+ */
20
+ type RequiredKeys<O extends object> = O extends unknown ? {
21
+ [K in keyof O]-?: {} extends Pick<O, K> ? never : K;
22
+ }[keyof O] : never;
23
+ type MergeObjectDeeply<O extends Record<string | number | symbol, unknown>, O1 extends Record<string | number | symbol, unknown>> = {
24
+ [K in keyof (O & O1)]: K extends RequiredKeys<O1> ? MergeObjectsOrReturnFallback<O[K], O1[K], O1[K]> : K extends OptionalKeys<O1> ? K extends OptionalKeys<O> ? MergeObjectsOrReturnFallback<Exclude<O[K], undefined>, Exclude<O1[K], undefined>, Exclude<O[K], undefined> | Exclude<O1[K], undefined>> : K extends RequiredKeys<O> ? Exclude<O1[K], undefined> extends O[K] ? O[K] : MergeObjectsOrReturnFallback<O[K], Exclude<O1[K], undefined>, O[K] | Exclude<O1[K], undefined>> : O1[K] : O[K];
25
+ };
26
+ type MergeObjectsOrReturnFallback<O, O1, Fallback> = O extends Record<string | number | symbol, unknown> ? O1 extends Record<string | number | symbol, unknown> ? MergeObjectDeeply<O, O1> : Fallback : Fallback;
27
+ /**
28
+ * Accurately merge the fields of `O` with the ones of `O1`. It is
29
+ * equivalent to the spread operator in JavaScript. [[Union]]s and [[Optional]]
30
+ * fields will be handled gracefully.
31
+ *
32
+ * (⚠️ needs `--strictNullChecks` enabled)
33
+ * @param O to complete
34
+ * @param O1 to copy from
35
+ * @returns [[Object]]
36
+ * @example
37
+ * ```ts
38
+ * import { PrettyPrint } from './PrettyPrint'
39
+ *
40
+ * type A1 = { a: number; b?: number; d?: number; e?: number; x: string; y?: number; z: string; } // prettier-ignore
41
+ * type A2 = { a?: number; c?: number; d?: number; e: number; x: number | undefined; y?: string; z?: number; } // prettier-ignore
42
+ *
43
+ * type Result = PrettyPrint<MergeDeep<A1, A2>>
44
+ * {
45
+ * a: number;
46
+ * b?: number | undefined;
47
+ * c?: number | undefined;
48
+ * d?: number | undefined;
49
+ * e: number;
50
+ * x: number | undefined;
51
+ * y?: string | number | undefined;
52
+ * z: string | number;
53
+ * }
54
+ * ```
55
+ */
56
+ export type MergeDeep<O extends Record<string | number | symbol, unknown>, O1 extends Record<string | number | symbol, unknown>> = O extends unknown ? (O1 extends unknown ? MergeObjectDeeply<O, O1> : never) : never;
57
+ export {};
@@ -0,0 +1,21 @@
1
+ export {};
2
+ // import { PrettyPrint } from './PrettyPrint'
3
+ // type A1 = { arr: string[]; barr?: { b: number } }
4
+ // type A2 = { arr?: number[]; barr?: { b: number } }
5
+ // type TestA = PrettyPrint<MergeDeep<A1, A2>>
6
+ // type B1 = { a: number; b?: number; d?: number; e?: number; x: string; y?: number; z: string; } // prettier-ignore
7
+ // type B2 = { a?: number; c?: number; d?: number; e: number; x: number | undefined; y?: string; z?: number; } // prettier-ignore
8
+ // type TestB = PrettyPrint<MergeDeep<B1, B2>>
9
+ // type C1 = { info: { time: string; newDate: Date; very: { deep: { prop: boolean } } } }
10
+ // type C2 = { info: { date: string; very: { deep: { prop: boolean } } } }
11
+ // type TestC = PrettyPrint<MergeDeep<C1, C2>>
12
+ // type D1 = { [key in string]?: { cool: boolean } | null }
13
+ // type D2 = { [key in string]?: { notCool: boolean } | null }
14
+ // type TestD = PrettyPrint<MergeDeep<D1, D2>>
15
+ // import { Timestamp } from '../../test/Timestamp'
16
+ // type T1 = { date: Timestamp }
17
+ // type T2 = { date: Timestamp }
18
+ // type TestT = MergeDeep<T1, T2>
19
+ // interface I1 { date: Timestamp }
20
+ // interface I2 { date: Timestamp }
21
+ // type TestI = MergeDeep<I1, I2>
@@ -0,0 +1,6 @@
1
+ type Has<U, U1> = [U1] extends [U] ? 1 : 0;
2
+ type If<B extends 0 | 1, Then, Else = never> = B extends 1 ? Then : Else;
3
+ export type PrettyPrint<A, Seen = never> = If<Has<Seen, A>, A, A extends Record<string | number | symbol, unknown> ? {
4
+ [K in keyof A]: PrettyPrint<A[K], A | Seen>;
5
+ } & unknown : A>;
6
+ export {};
@@ -0,0 +1,4 @@
1
+ export {};
2
+ // import { Timestamp } from '../../test/Timestamp'
3
+ // type T1 = { b: string } & { nested: { props: number[] } } & { date: Timestamp[]; d: any[] }
4
+ // type Test1 = PrettyPrint<T1>
package/package.json CHANGED
@@ -1,40 +1,34 @@
1
1
  {
2
2
  "name": "merge-anything",
3
- "version": "5.1.7",
3
+ "version": "6.0.1",
4
4
  "description": "Merge objects & other types recursively. A simple & small integration.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
- "types": "./dist/index.d.ts",
8
- "module": "./dist/index.js",
9
- "main": "./dist/index.js",
10
7
  "exports": {
11
- ".": {
12
- "require": {
13
- "types": "./dist/cjs/index.d.cts",
14
- "default": "./dist/cjs/index.cjs"
15
- },
16
- "import": {
17
- "types": "./dist/index.d.ts",
18
- "default": "./dist/index.js"
19
- }
20
- }
8
+ ".": "./dist/index.js"
21
9
  },
22
- "files": [
23
- "dist"
24
- ],
25
10
  "engines": {
26
- "node": ">=12.13"
11
+ "node": ">=18"
27
12
  },
28
13
  "scripts": {
29
- "lint": "tsc --noEmit && eslint ./src --ext .ts",
14
+ "lint": "tsc --noEmit && eslint ./src",
30
15
  "test": "vitest run",
31
- "build": "rollup -c ./rollup.config.js",
32
- "release": "npm run lint && del dist && npm run build && np"
16
+ "build": "del-cli dist && tsc",
17
+ "release": "npm run lint && npm run build && np"
33
18
  },
34
- "repository": {
35
- "type": "git",
36
- "url": "git+https://github.com/mesqueeb/merge-anything.git"
19
+ "dependencies": {
20
+ "is-what": "^4.1.8"
37
21
  },
22
+ "devDependencies": {
23
+ "del-cli": "^5.1.0",
24
+ "np": "^10.0.5",
25
+ "vitest": "^1.6.0",
26
+ "@cycraft/eslint": "^0.3.0",
27
+ "@cycraft/tsconfig": "^0.1.2"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
38
32
  "keywords": [
39
33
  "javascript",
40
34
  "merge",
@@ -57,60 +51,13 @@
57
51
  "merge-combine",
58
52
  "nested-combine"
59
53
  ],
60
- "author": "Luca Ban - Mesqueeb",
54
+ "author": "Luca Ban - Mesqueeb (https://cycraft.co)",
61
55
  "funding": "https://github.com/sponsors/mesqueeb",
62
56
  "license": "MIT",
63
- "bugs": {
64
- "url": "https://github.com/mesqueeb/merge-anything/issues"
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/mesqueeb/merge-anything.git"
65
60
  },
66
61
  "homepage": "https://github.com/mesqueeb/merge-anything#readme",
67
- "dependencies": {
68
- "is-what": "^4.1.8"
69
- },
70
- "devDependencies": {
71
- "@typescript-eslint/eslint-plugin": "^5.59.2",
72
- "@typescript-eslint/parser": "^5.59.2",
73
- "del-cli": "^5.0.0",
74
- "eslint": "^8.40.0",
75
- "eslint-config-prettier": "^8.8.0",
76
- "eslint-plugin-tree-shaking": "^1.10.0",
77
- "np": "^7.7.0",
78
- "prettier": "^2.8.8",
79
- "rollup": "^3.23.0",
80
- "rollup-plugin-dts": "^5.3.0",
81
- "rollup-plugin-esbuild": "^5.0.0",
82
- "typescript": "^5.0.4",
83
- "vitest": "^0.31.0"
84
- },
85
- "np": {
86
- "yarn": false,
87
- "branch": "production"
88
- },
89
- "eslintConfig": {
90
- "ignorePatterns": [
91
- "node_modules",
92
- "dist",
93
- "scripts",
94
- "test"
95
- ],
96
- "root": true,
97
- "parser": "@typescript-eslint/parser",
98
- "plugins": [
99
- "@typescript-eslint",
100
- "tree-shaking"
101
- ],
102
- "extends": [
103
- "eslint:recommended",
104
- "plugin:@typescript-eslint/eslint-recommended",
105
- "plugin:@typescript-eslint/recommended",
106
- "prettier"
107
- ],
108
- "rules": {
109
- "@typescript-eslint/no-empty-function": "off",
110
- "@typescript-eslint/no-explicit-any": "off",
111
- "@typescript-eslint/ban-ts-ignore": "off",
112
- "tree-shaking/no-side-effects-in-initialization": "error",
113
- "@typescript-eslint/ban-ts-comment": "off"
114
- }
115
- }
62
+ "bugs": "https://github.com/mesqueeb/merge-anything/issues"
116
63
  }
@@ -1,83 +0,0 @@
1
- 'use strict';
2
-
3
- const isWhat = require('is-what');
4
-
5
- function concatArrays(originVal, newVal) {
6
- if (isWhat.isArray(originVal) && isWhat.isArray(newVal)) {
7
- return originVal.concat(newVal);
8
- }
9
- return newVal;
10
- }
11
-
12
- function assignProp(carry, key, newVal, originalObject) {
13
- const propType = {}.propertyIsEnumerable.call(originalObject, key) ? "enumerable" : "nonenumerable";
14
- if (propType === "enumerable")
15
- carry[key] = newVal;
16
- if (propType === "nonenumerable") {
17
- Object.defineProperty(carry, key, {
18
- value: newVal,
19
- enumerable: false,
20
- writable: true,
21
- configurable: true
22
- });
23
- }
24
- }
25
- function mergeRecursively(origin, newComer, compareFn) {
26
- if (!isWhat.isPlainObject(newComer))
27
- return newComer;
28
- let newObject = {};
29
- if (isWhat.isPlainObject(origin)) {
30
- const props2 = Object.getOwnPropertyNames(origin);
31
- const symbols2 = Object.getOwnPropertySymbols(origin);
32
- newObject = [...props2, ...symbols2].reduce((carry, key) => {
33
- const targetVal = origin[key];
34
- if (!isWhat.isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key) || isWhat.isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key)) {
35
- assignProp(
36
- carry,
37
- key,
38
- targetVal,
39
- origin
40
- );
41
- }
42
- return carry;
43
- }, {});
44
- }
45
- const props = Object.getOwnPropertyNames(newComer);
46
- const symbols = Object.getOwnPropertySymbols(newComer);
47
- const result = [...props, ...symbols].reduce((carry, key) => {
48
- let newVal = newComer[key];
49
- const targetVal = isWhat.isPlainObject(origin) ? origin[key] : void 0;
50
- if (targetVal !== void 0 && isWhat.isPlainObject(newVal)) {
51
- newVal = mergeRecursively(targetVal, newVal, compareFn);
52
- }
53
- const propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
54
- assignProp(
55
- carry,
56
- key,
57
- propToAssign,
58
- newComer
59
- );
60
- return carry;
61
- }, newObject);
62
- return result;
63
- }
64
- function merge(object, ...otherObjects) {
65
- return otherObjects.reduce((result, newComer) => {
66
- return mergeRecursively(result, newComer);
67
- }, object);
68
- }
69
- function mergeAndCompare(compareFn, object, ...otherObjects) {
70
- return otherObjects.reduce((result, newComer) => {
71
- return mergeRecursively(result, newComer, compareFn);
72
- }, object);
73
- }
74
- function mergeAndConcat(object, ...otherObjects) {
75
- return otherObjects.reduce((result, newComer) => {
76
- return mergeRecursively(result, newComer, concatArrays);
77
- }, object);
78
- }
79
-
80
- exports.concatArrays = concatArrays;
81
- exports.merge = merge;
82
- exports.mergeAndCompare = mergeAndCompare;
83
- exports.mergeAndConcat = mergeAndConcat;