ts-data-forge 6.8.0 → 6.9.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.
- package/dist/array/impl/array-utils-set-op.d.mts.map +1 -1
- package/dist/array/impl/array-utils-set-op.mjs +1 -3
- package/dist/array/impl/array-utils-set-op.mjs.map +1 -1
- package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-validation.mjs +2 -6
- package/dist/array/impl/array-utils-validation.mjs.map +1 -1
- package/dist/object/object.d.mts +52 -0
- package/dist/object/object.d.mts.map +1 -1
- package/dist/object/object.mjs +103 -1
- package/dist/object/object.mjs.map +1 -1
- package/dist/others/fast-deep-equal.d.mts.map +1 -1
- package/dist/others/fast-deep-equal.mjs +0 -1
- package/dist/others/fast-deep-equal.mjs.map +1 -1
- package/package.json +20 -20
- package/src/array/impl/array-utils-overload-type-error.test.mts +2 -4
- package/src/array/impl/array-utils-set-op.mts +0 -1
- package/src/array/impl/array-utils-validation.mts +2 -6
- package/src/functional/optional.test.mts +5 -7
- package/src/functional/result.test.mts +8 -10
- package/src/functional/ternary-result.test.mts +4 -4
- package/src/json/json.test.mts +5 -5
- package/src/number/branded-types/finite-number.test.mts +11 -15
- package/src/number/branded-types/int.test.mts +13 -13
- package/src/number/branded-types/int16.test.mts +15 -15
- package/src/number/branded-types/int32.test.mts +15 -15
- package/src/number/branded-types/non-negative-finite-number.test.mts +15 -19
- package/src/number/branded-types/non-negative-int16.test.mts +15 -15
- package/src/number/branded-types/non-negative-int32.test.mts +15 -15
- package/src/number/branded-types/non-zero-finite-number.test.mts +18 -18
- package/src/number/branded-types/non-zero-int.test.mts +14 -18
- package/src/number/branded-types/non-zero-int16.test.mts +15 -19
- package/src/number/branded-types/non-zero-int32.test.mts +15 -19
- package/src/number/branded-types/non-zero-safe-int.test.mts +18 -22
- package/src/number/branded-types/non-zero-uint16.test.mts +15 -15
- package/src/number/branded-types/non-zero-uint32.test.mts +15 -15
- package/src/number/branded-types/positive-finite-number.test.mts +18 -18
- package/src/number/branded-types/positive-int.test.mts +16 -22
- package/src/number/branded-types/positive-int16.test.mts +14 -14
- package/src/number/branded-types/positive-int32.test.mts +14 -14
- package/src/number/branded-types/positive-safe-int.test.mts +18 -20
- package/src/number/branded-types/positive-uint16.test.mts +15 -15
- package/src/number/branded-types/positive-uint32.test.mts +15 -15
- package/src/number/branded-types/safe-int.test.mts +17 -21
- package/src/number/branded-types/safe-uint.test.mts +16 -22
- package/src/number/branded-types/uint.test.mts +14 -14
- package/src/number/branded-types/uint16.test.mts +14 -14
- package/src/number/branded-types/uint32.test.mts +14 -14
- package/src/number/enum/int8.test.mts +1 -1
- package/src/number/enum/uint8.test.mts +1 -1
- package/src/object/object.mts +170 -1
- package/src/object/object.test.mts +172 -0
- package/src/others/fast-deep-equal.mts +0 -1
- package/src/others/unknown-to-string.test.mts +1 -1
|
@@ -472,3 +472,175 @@ describe('merge', () => {
|
|
|
472
472
|
assert.deepStrictEqual(result, { a: 1, b: 'text', c: true, d: 42 });
|
|
473
473
|
});
|
|
474
474
|
});
|
|
475
|
+
|
|
476
|
+
describe('deepPick', () => {
|
|
477
|
+
test('should deeply pick a nested property', () => {
|
|
478
|
+
const data = { a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 } as const;
|
|
479
|
+
|
|
480
|
+
const result = Obj.deepPick(data, ['a', 'b', 'c']);
|
|
481
|
+
|
|
482
|
+
assert.deepStrictEqual(result, { a: { b: { c: 1 } } });
|
|
483
|
+
|
|
484
|
+
expectType<
|
|
485
|
+
typeof result,
|
|
486
|
+
Readonly<{ a: Readonly<{ b: Readonly<{ c: 1 }> }> }>
|
|
487
|
+
>('=');
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
test('should pick at depth 1', () => {
|
|
491
|
+
const data = { a: 1, b: 2, c: 3 } as const;
|
|
492
|
+
|
|
493
|
+
const result = Obj.deepPick(data, ['a']);
|
|
494
|
+
|
|
495
|
+
assert.deepStrictEqual(result, { a: 1 });
|
|
496
|
+
|
|
497
|
+
expectType<typeof result, Readonly<{ a: 1 }>>('=');
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
test('should pick at depth 2', () => {
|
|
501
|
+
const data = { a: { b: 10, c: 20 }, d: 30 } as const;
|
|
502
|
+
|
|
503
|
+
const result = Obj.deepPick(data, ['a', 'b']);
|
|
504
|
+
|
|
505
|
+
assert.deepStrictEqual(result, { a: { b: 10 } });
|
|
506
|
+
|
|
507
|
+
expectType<typeof result, Readonly<{ a: Readonly<{ b: 10 }> }>>('=');
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
test('should return empty object for non-existent key', () => {
|
|
511
|
+
const data = { a: 1 } as const;
|
|
512
|
+
|
|
513
|
+
const result = Obj.deepPick(data, ['x']);
|
|
514
|
+
|
|
515
|
+
assert.deepStrictEqual(result, {});
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
test('should return empty nested for non-existent nested key', () => {
|
|
519
|
+
const data = { a: { b: 1 } } as const;
|
|
520
|
+
|
|
521
|
+
const result = Obj.deepPick(data, ['a', 'x']);
|
|
522
|
+
|
|
523
|
+
assert.deepStrictEqual(result, { a: {} });
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
test('should support curried form with correct type inference', () => {
|
|
527
|
+
const pickABC = Obj.deepPick(['a', 'b', 'c']);
|
|
528
|
+
|
|
529
|
+
const data = { a: { b: { c: 42, d: 99 } } } as const;
|
|
530
|
+
|
|
531
|
+
const result = pickABC(data);
|
|
532
|
+
|
|
533
|
+
assert.deepStrictEqual(result, { a: { b: { c: 42 } } });
|
|
534
|
+
|
|
535
|
+
expectType<
|
|
536
|
+
typeof result,
|
|
537
|
+
Readonly<{ a: Readonly<{ b: Readonly<{ c: 42 }> }> }>
|
|
538
|
+
>('=');
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
test('should work with pipe when curried with correct type inference', () => {
|
|
542
|
+
const pickNested = Obj.deepPick(['a', 'b']);
|
|
543
|
+
|
|
544
|
+
const data = { a: { b: 1, c: 2 }, d: 3 } as const;
|
|
545
|
+
|
|
546
|
+
const result = pipe(data).map(pickNested).value;
|
|
547
|
+
|
|
548
|
+
assert.deepStrictEqual(result, { a: { b: 1 } });
|
|
549
|
+
|
|
550
|
+
expectType<typeof result, Readonly<{ a: Readonly<{ b: 1 }> }>>('=');
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
test('should return {} for path through primitive', () => {
|
|
554
|
+
const data = { a: 42 } as const;
|
|
555
|
+
|
|
556
|
+
const result = Obj.deepPick(data, ['a', 'b']);
|
|
557
|
+
|
|
558
|
+
assert.deepStrictEqual(result, { a: {} });
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
describe('deepOmit', () => {
|
|
563
|
+
test('should deeply omit a nested property', () => {
|
|
564
|
+
const data = { a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 } as const;
|
|
565
|
+
|
|
566
|
+
const result = Obj.deepOmit(data, ['a', 'b', 'c']);
|
|
567
|
+
|
|
568
|
+
assert.deepStrictEqual(result, { a: { b: { d: 2 }, e: 3 }, f: 4 });
|
|
569
|
+
|
|
570
|
+
expectType<
|
|
571
|
+
typeof result,
|
|
572
|
+
Readonly<{ a: Readonly<{ b: Readonly<{ d: 2 }>; e: 3 }>; f: 4 }>
|
|
573
|
+
>('=');
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
test('should omit at depth 1', () => {
|
|
577
|
+
const data = { a: 1, b: 2, c: 3 } as const;
|
|
578
|
+
|
|
579
|
+
const result = Obj.deepOmit(data, ['a']);
|
|
580
|
+
|
|
581
|
+
assert.deepStrictEqual(result, { b: 2, c: 3 });
|
|
582
|
+
|
|
583
|
+
expectType<typeof result, Readonly<{ b: 2; c: 3 }>>('=');
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
test('should omit at depth 2', () => {
|
|
587
|
+
const data = { a: { b: 10, c: 20 }, d: 30 } as const;
|
|
588
|
+
|
|
589
|
+
const result = Obj.deepOmit(data, ['a', 'b']);
|
|
590
|
+
|
|
591
|
+
assert.deepStrictEqual(result, { a: { c: 20 }, d: 30 });
|
|
592
|
+
|
|
593
|
+
expectType<typeof result, Readonly<{ a: Readonly<{ c: 20 }>; d: 30 }>>('=');
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
test('should return unchanged for non-existent key', () => {
|
|
597
|
+
const data = { a: 1, b: 2 } as const;
|
|
598
|
+
|
|
599
|
+
const result = Obj.deepOmit(data, ['x']);
|
|
600
|
+
|
|
601
|
+
assert.deepStrictEqual(result, { a: 1, b: 2 });
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
test('should return unchanged for non-existent nested key', () => {
|
|
605
|
+
const data = { a: { b: 1 } } as const;
|
|
606
|
+
|
|
607
|
+
const result = Obj.deepOmit(data, ['a', 'x']);
|
|
608
|
+
|
|
609
|
+
assert.deepStrictEqual(result, { a: { b: 1 } });
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
test('should return unchanged for path through primitive', () => {
|
|
613
|
+
const data = { a: 42, b: 'hello' } as const;
|
|
614
|
+
|
|
615
|
+
const result = Obj.deepOmit(data, ['a', 'toString']);
|
|
616
|
+
|
|
617
|
+
assert.deepStrictEqual(result, { a: 42, b: 'hello' });
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
test('should support curried form with correct type inference', () => {
|
|
621
|
+
const omitABC = Obj.deepOmit(['a', 'b', 'c']);
|
|
622
|
+
|
|
623
|
+
const data = { a: { b: { c: 1, d: 2 } } } as const;
|
|
624
|
+
|
|
625
|
+
const result = omitABC(data);
|
|
626
|
+
|
|
627
|
+
assert.deepStrictEqual(result, { a: { b: { d: 2 } } });
|
|
628
|
+
|
|
629
|
+
expectType<
|
|
630
|
+
typeof result,
|
|
631
|
+
Readonly<{ a: Readonly<{ b: Readonly<{ d: 2 }> }> }>
|
|
632
|
+
>('=');
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
test('should work with pipe when curried with correct type inference', () => {
|
|
636
|
+
const omitNested = Obj.deepOmit(['a', 'b']);
|
|
637
|
+
|
|
638
|
+
const data = { a: { b: 1, c: 2 }, d: 3 } as const;
|
|
639
|
+
|
|
640
|
+
const result = pipe(data).map(omitNested).value;
|
|
641
|
+
|
|
642
|
+
assert.deepStrictEqual(result, { a: { c: 2 }, d: 3 });
|
|
643
|
+
|
|
644
|
+
expectType<typeof result, Readonly<{ a: Readonly<{ c: 2 }>; d: 3 }>>('=');
|
|
645
|
+
});
|
|
646
|
+
});
|