type-plus 4.0.1 → 4.2.0

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.
Files changed (50) hide show
  1. package/README.md +6 -4
  2. package/cjs/array/CreateTuple.d.ts +3 -0
  3. package/cjs/array/Last.d.ts +4 -0
  4. package/cjs/array/Last.js +3 -0
  5. package/cjs/array/Last.js.map +1 -0
  6. package/cjs/array/Tail.d.ts +3 -0
  7. package/cjs/array/index.d.ts +1 -0
  8. package/cjs/array/index.js +5 -1
  9. package/cjs/array/index.js.map +1 -1
  10. package/cjs/assertion/index.js +5 -1
  11. package/cjs/assertion/index.js.map +1 -1
  12. package/cjs/class/index.js +5 -1
  13. package/cjs/class/index.js.map +1 -1
  14. package/cjs/index.js +5 -1
  15. package/cjs/index.js.map +1 -1
  16. package/cjs/nodejs/index.js +5 -1
  17. package/cjs/nodejs/index.js.map +1 -1
  18. package/cjs/nominal-types/index.js +5 -1
  19. package/cjs/nominal-types/index.js.map +1 -1
  20. package/cjs/object/index.d.ts +2 -1
  21. package/cjs/object/index.js +6 -1
  22. package/cjs/object/index.js.map +1 -1
  23. package/cjs/object/split.d.ts +84 -0
  24. package/cjs/object/split.js +25 -0
  25. package/cjs/object/split.js.map +1 -0
  26. package/cjs/predicates/index.js +5 -1
  27. package/cjs/predicates/index.js.map +1 -1
  28. package/cjs/promise/index.js +5 -1
  29. package/cjs/promise/index.js.map +1 -1
  30. package/cjs/utils/index.js +5 -1
  31. package/cjs/utils/index.js.map +1 -1
  32. package/esm/array/Last.js +2 -0
  33. package/esm/array/Last.js.map +1 -0
  34. package/esm/array/index.js.map +1 -1
  35. package/esm/object/index.js +1 -0
  36. package/esm/object/index.js.map +1 -1
  37. package/esm/object/split.js +8 -0
  38. package/esm/object/split.js.map +1 -0
  39. package/package.json +19 -18
  40. package/ts/array/CreateTuple.ts +10 -7
  41. package/ts/array/Last.spec.ts +32 -0
  42. package/ts/array/Last.ts +4 -0
  43. package/ts/array/Tail.spec.ts +32 -32
  44. package/ts/array/Tail.ts +10 -7
  45. package/ts/array/index.ts +1 -0
  46. package/ts/index.spec.ts +6 -4
  47. package/ts/object/Partial.spec.ts +49 -49
  48. package/ts/object/index.ts +2 -2
  49. package/ts/object/split.spec.ts +54 -0
  50. package/ts/object/split.ts +195 -0
package/README.md CHANGED
@@ -345,7 +345,7 @@ type No = IsAny<1, 'yes', 'no'> // 'no'
345
345
 
346
346
  - `CommonPropKeys<A>`: gets common keys inside the records in the array `A` (deprecate `CommonKeys`).
347
347
  - `Concat<A, B>`: `[...A, ...B]`.
348
- - `CreateTuple<L, T>`: creates `Tuple<T>` with `L` number of elements.
348
+ - `CreateTuple<L, T>`: Creates `Tuple<T>` with `L` number of elements.
349
349
  - `DropFirst<A>`: drops the first value type of `A`.
350
350
  - `DropLast<A>`: drops the last value type of `A`.
351
351
  - `Filter<A, Criteria>`: gets the array of types satisfying `Criteria` in `A`.
@@ -354,13 +354,14 @@ type No = IsAny<1, 'yes', 'no'> // 'no'
354
354
  - `Head<A>`: gets the first entry in the array.
355
355
  - `IntersectOfProps<A, K>`: gets the intersect of `A[K]` types (deprecate `MapToProp`)
356
356
  - `IsArray<T>`: `logical` predicate for `Array`.
357
+ - `Last<A>`: gets the last type of an array or tuple.
357
358
  - `literalArray(...entries)`: return an array whose items are restricted to the provided literals.
358
359
  - `PadLeft<A, Total, PadWith>`: pads `A` with `PadWith` if the length of `A` is less than `L`.
359
360
  - `reduceWhile()`: `reduce()` with predicate for early termination. \
360
361
  A simple version of the same function in the `ramda` package.
361
362
  - `Reverse<A>`: reverses the order of `A`.
362
363
  - `Some<A, Criteria>`: true if some elements in `A` matches `Criteria`.
363
- - `Tail<A>`: gets the remaining entries in the array except the first.
364
+ - `Tail<A>`: Gets the types of a tuple except the first entry.
364
365
  - `UnionOfProps<A, K>`: gets the union of `A[K]` types (deprecate `PropUnion`).
365
366
  - `UnionOfValues<A>`: gets the union of value types in `A` (deprecate `ArrayValue`).
366
367
 
@@ -397,7 +398,7 @@ JSONTypes.get<string>(someJson, 'a', 'b', 1, 'c') // miku
397
398
  - `IsRecord<T>`: `logical` predicate for `Record`.
398
399
  - `KeysWithDiffTypes<A, B>`: gets the keys common in `A` and `B` but with different value type.
399
400
  - `mapKey()`: type adjusted map by key.
400
- - `reduceKey()`: type adjusted reduce by key.
401
+ - `reduceByKey()`: type adjusted reduce by key.
401
402
  - `someKey()`: type adjusted some by key.
402
403
  - `SpreadRecord<A, B>`: type for `{...a, ...b}` when both `a` and `b` are `Record`. \
403
404
  for array, just do `[...A, ...B]`.
@@ -489,10 +490,11 @@ So you may encounter some weird behavior if your logic is complex.
489
490
  - `hasProperty(value, prop)`: assert `value` has property `prop`. This will pick the correct union type.
490
491
  - `isConstructor(subject)`: type guard `subject` is a constructor.
491
492
  - `isSystemError(code, err)`: type guard `err` with Nodejs error code.
492
- - `pick(obj, ...props)`: pick properties from `obj`.
493
493
  - `omit(obj, ...props)`: omit properties from `obj`.
494
+ - `pick(obj, ...props)`: pick properties from `obj`.
494
495
  - `required(...)`: merge options and removing `Partial<T>`. From [`unpartial`](https://github.com/unional/unpartial)
495
496
  - `requiredDeep(...)`: merge options deeply and removing `Partial<T>`. From [`unpartial`](https://github.com/unional/unpartial)
497
+ - `split(target, ...splitters)`: split one object into multiple objects.
496
498
  - `typeOverrideIncompatible<T>()`: override only the incompatible portion between two types.
497
499
 
498
500
  ```ts
@@ -1,4 +1,7 @@
1
1
  import { IsPositive } from '../math';
2
+ /**
3
+ * Creates `Tuple<T>` with `L` number of elements.
4
+ */
2
5
  export declare type CreateTuple<L extends number, T = any> = IsPositive<L> extends true ? Device<[], L, T> : never;
3
6
  declare type Device<R extends any[], L extends number, T> = R['length'] extends L ? R : Device<[T, ...R], L, T>;
4
7
  export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Get the last type of an array or tuple.
3
+ */
4
+ export declare type Last<T extends any[]> = T extends [...any[], infer R] ? R : T[0];
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=Last.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Last.js","sourceRoot":"","sources":["../../ts/array/Last.ts"],"names":[],"mappings":""}
@@ -1,2 +1,5 @@
1
1
  import { UnionOfValues } from './UnionOfValues';
2
+ /**
3
+ * Gets the types of a tuple except the first entry.
4
+ */
2
5
  export declare type Tail<T extends any[]> = T['length'] extends 0 ? never : (T extends [any, ...infer Tail] ? (Tail extends UnionOfValues<T>[] ? Tail : never) : T);
@@ -9,6 +9,7 @@ export type { FindLast } from './FindLast';
9
9
  export type { Head } from './Head';
10
10
  export type { IntersectOfProps, MapToProp } from './IntersectOfProps';
11
11
  export type { IsArray } from './IsArray';
12
+ export type { Last } from './Last';
12
13
  export * from './literalArray';
13
14
  export type { PadLeft } from './PadLeft';
14
15
  export * from './reduceWhile';
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAWA,iDAA8B;AAE9B,gDAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAYA,iDAA8B;AAE9B,gDAA6B"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/assertion/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/assertion/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA4B"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/class/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,kDAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/class/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,kDAA+B"}
package/cjs/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,mCAAmC;AACnC,uCAAkD;AAAzC,qGAAA,QAAQ,OAAA;AAAE,yGAAA,YAAY,OAAA;AAC/B,0CAAuB;AACvB,8CAA2B;AAC3B,0CAAuB;AAEvB,6CAA0B;AAC1B,+CAA4B;AAC5B,8CAA2B;AAC3B,yCAAsB;AACtB,2CAAwB;AACxB,kDAA+B;AAC/B,2CAAwB;AACxB,+CAA4B;AAE5B,4CAAyB;AAIzB,0CAAuB;AACvB,+BAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAmC;AACnC,uCAAkD;AAAzC,qGAAA,QAAQ,OAAA;AAAE,yGAAA,YAAY,OAAA;AAC/B,0CAAuB;AACvB,8CAA2B;AAC3B,0CAAuB;AAEvB,6CAA0B;AAC1B,+CAA4B;AAC5B,8CAA2B;AAC3B,yCAAsB;AACtB,2CAAwB;AACxB,kDAA+B;AAC/B,2CAAwB;AACxB,+CAA4B;AAE5B,4CAAyB;AAIzB,0CAAuB;AACvB,+BAA+B"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/nodejs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,gDAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/nodejs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA6B"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/nominal-types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0CAAuB;AACvB,2CAAwB;AACxB,iDAA8B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/nominal-types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAuB;AACvB,2CAAwB;AACxB,iDAA8B"}
@@ -19,7 +19,7 @@ export * from './mapKey';
19
19
  export * from './mapProperties';
20
20
  export * from './omit';
21
21
  export type { OptionalKeys } from './OptionalKeys';
22
- export type { PartialOmit, PartialPick } from './Partial';
22
+ export type { PartialExcept, PartialOmit, PartialPick } from './Partial';
23
23
  export * from './pick';
24
24
  export type { RecursiveIntersect } from './RecursiveIntersect';
25
25
  export type { RecursivePartial } from './RecursivePartial';
@@ -29,6 +29,7 @@ export * from './replaceProperty';
29
29
  export type { RequiredExcept, RequiredPick } from './Required';
30
30
  export type { RequiredKeys } from './RequiredKeys';
31
31
  export * from './someKey';
32
+ export * from './split';
32
33
  export type { SpreadRecord } from './SpreadRecord';
33
34
  export * from './typeOverrideIncompatible';
34
35
  export type { ValueOf } from './ValueOf';
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -25,5 +29,6 @@ __exportStar(require("./pick"), exports);
25
29
  __exportStar(require("./reduceKey"), exports);
26
30
  __exportStar(require("./replaceProperty"), exports);
27
31
  __exportStar(require("./someKey"), exports);
32
+ __exportStar(require("./split"), exports);
28
33
  __exportStar(require("./typeOverrideIncompatible"), exports);
29
34
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/object/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,6CAA0B;AAE1B,2CAAwB;AACxB,8CAA2B;AAC3B,4CAAyB;AACzB,+CAA4B;AAC5B,6CAA0B;AAC1B,2CAAwB;AACxB,gDAA6B;AAO7B,2CAAwB;AACxB,kDAA+B;AAC/B,yCAAsB;AAGtB,yCAAsB;AAItB,8CAA2B;AAC3B,oDAAiC;AAGjC,4CAAyB;AAEzB,6DAA0C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/object/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAEA,6CAA0B;AAE1B,2CAAwB;AACxB,8CAA2B;AAC3B,4CAAyB;AACzB,+CAA4B;AAC5B,6CAA0B;AAC1B,2CAAwB;AACxB,gDAA6B;AAO7B,2CAAwB;AACxB,kDAA+B;AAC/B,yCAAsB;AAGtB,yCAAsB;AAItB,8CAA2B;AAC3B,oDAAiC;AAGjC,4CAAyB;AACzB,0CAAuB;AAEvB,6DAA0C"}
@@ -0,0 +1,84 @@
1
+ import { AnyRecord, Omit } from '..';
2
+ declare type Splitter<T extends AnyRecord> = Partial<{
3
+ [k in keyof T]: T[k] | undefined;
4
+ }>;
5
+ declare type Split<T extends AnyRecord, S extends AnyRecord> = {
6
+ [k in keyof S]: NonNullable<T[k]> | S[k];
7
+ };
8
+ /**
9
+ * Split an object into multiple objects.
10
+ * @returns [...entries, remaining]
11
+ */
12
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>>(target: T, split1: S1): [
13
+ Split<T, S1>,
14
+ Omit<T, keyof S1>
15
+ ];
16
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>>(target: T, split1: S1, split2: S2): [
17
+ Split<T, S1>,
18
+ Split<T, S2>,
19
+ Omit<T, keyof S1 | keyof S2>
20
+ ];
21
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3): [
22
+ Split<T, S1>,
23
+ Split<T, S2>,
24
+ Split<T, S3>,
25
+ Omit<T, keyof S1 | keyof S2 | keyof S3>
26
+ ];
27
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4): [
28
+ Split<T, S1>,
29
+ Split<T, S2>,
30
+ Split<T, S3>,
31
+ Split<T, S4>,
32
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4>
33
+ ];
34
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5): [
35
+ Split<T, S1>,
36
+ Split<T, S2>,
37
+ Split<T, S3>,
38
+ Split<T, S4>,
39
+ Split<T, S5>,
40
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5>
41
+ ];
42
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6): [
43
+ Split<T, S1>,
44
+ Split<T, S2>,
45
+ Split<T, S3>,
46
+ Split<T, S4>,
47
+ Split<T, S5>,
48
+ Split<T, S6>,
49
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6>
50
+ ];
51
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>, S7 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6, splitter7: S7): [
52
+ Split<T, S1>,
53
+ Split<T, S2>,
54
+ Split<T, S3>,
55
+ Split<T, S4>,
56
+ Split<T, S5>,
57
+ Split<T, S6>,
58
+ Split<T, S7>,
59
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7>
60
+ ];
61
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>, S7 extends Splitter<T>, S8 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6, splitter7: S7, splitter8: S8): [
62
+ Split<T, S1>,
63
+ Split<T, S2>,
64
+ Split<T, S3>,
65
+ Split<T, S4>,
66
+ Split<T, S5>,
67
+ Split<T, S6>,
68
+ Split<T, S7>,
69
+ Split<T, S8>,
70
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7 | keyof S8>
71
+ ];
72
+ export declare function split<T extends AnyRecord, S1 extends Splitter<T>, S2 extends Splitter<T>, S3 extends Splitter<T>, S4 extends Splitter<T>, S5 extends Splitter<T>, S6 extends Splitter<T>, S7 extends Splitter<T>, S8 extends Splitter<T>, S9 extends Splitter<T>>(target: T, splitter1: S1, splitter2: S2, splitter3: S3, splitter4: S4, splitter5: S5, splitter6: S6, splitter7: S7, splitter8: S8, splitter9: S9): [
73
+ Split<T, S1>,
74
+ Split<T, S2>,
75
+ Split<T, S3>,
76
+ Split<T, S4>,
77
+ Split<T, S5>,
78
+ Split<T, S6>,
79
+ Split<T, S7>,
80
+ Split<T, S8>,
81
+ Split<T, S9>,
82
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7 | keyof S8 | keyof S9>
83
+ ];
84
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.split = void 0;
13
+ var __1 = require("..");
14
+ function split(target) {
15
+ var splitters = [];
16
+ for (var _i = 1; _i < arguments.length; _i++) {
17
+ splitters[_i - 1] = arguments[_i];
18
+ }
19
+ var keyMap = {};
20
+ var s = splitters.map(function (s) { return (0, __1.reduceByKey)(s, function (p, k) { var _a; return (keyMap[k] = true, p[k] = (_a = target[k]) !== null && _a !== void 0 ? _a : s[k], p); }, {}); });
21
+ var r = (0, __1.reduceByKey)(target, function (p, k) { return keyMap[k] ? p : (p[k] = target[k], p); }, {});
22
+ return __spreadArray(__spreadArray([], s, true), [r], false);
23
+ }
24
+ exports.split = split;
25
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../ts/object/split.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wBAAiD;AA6LjD,SAAgB,KAAK,CAAC,MAAiB;IAAE,mBAAyB;SAAzB,UAAyB,EAAzB,qBAAyB,EAAzB,IAAyB;QAAzB,kCAAyB;;IAChE,IAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,IAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,IAAA,eAAW,EAAC,CAAC,EAAE,UAAC,CAAC,EAAE,CAAC,YAAK,OAAA,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAA,MAAM,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,EAAA,EAAE,EAAe,CAAC,EAA1F,CAA0F,CAAC,CAAA;IACxH,IAAM,CAAC,GAAG,IAAA,eAAW,EAAC,MAAM,EAAE,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAArC,CAAqC,EAAE,EAAe,CAAC,CAAA;IAC/F,uCAAW,CAAC,UAAE,CAAC,UAAC;AAClB,CAAC;AALD,sBAKC"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/predicates/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAA2B;AAI3B,2CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/predicates/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B;AAI3B,2CAAwB"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/promise/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAA2B;AAG3B,8CAA2B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/promise/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B;AAG3B,8CAA2B"}
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uCAAoB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uCAAoB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Last.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Last.js","sourceRoot":"","sources":["../../ts/array/Last.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":"AAWA,cAAc,gBAAgB,CAAA;AAE9B,cAAc,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":"AAYA,cAAc,gBAAgB,CAAA;AAE9B,cAAc,eAAe,CAAA"}
@@ -13,5 +13,6 @@ export * from './pick';
13
13
  export * from './reduceKey';
14
14
  export * from './replaceProperty';
15
15
  export * from './someKey';
16
+ export * from './split';
16
17
  export * from './typeOverrideIncompatible';
17
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/object/index.ts"],"names":[],"mappings":"AAEA,cAAc,YAAY,CAAA;AAE1B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAO7B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,QAAQ,CAAA;AAGtB,cAAc,QAAQ,CAAA;AAItB,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AAGjC,cAAc,WAAW,CAAA;AAEzB,cAAc,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/object/index.ts"],"names":[],"mappings":"AAEA,cAAc,YAAY,CAAA;AAE1B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAO7B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,QAAQ,CAAA;AAGtB,cAAc,QAAQ,CAAA;AAItB,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AAGjC,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AAEvB,cAAc,4BAA4B,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { reduceByKey } from '..';
2
+ export function split(target, ...splitters) {
3
+ const keyMap = {};
4
+ const s = splitters.map(s => reduceByKey(s, (p, k) => (keyMap[k] = true, p[k] = target[k] ?? s[k], p), {}));
5
+ const r = reduceByKey(target, (p, k) => keyMap[k] ? p : (p[k] = target[k], p), {});
6
+ return [...s, r];
7
+ }
8
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../ts/object/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,WAAW,EAAE,MAAM,IAAI,CAAA;AA6LjD,MAAM,UAAU,KAAK,CAAC,MAAiB,EAAE,GAAG,SAAsB;IAChE,MAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAe,CAAC,CAAC,CAAA;IACxH,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAe,CAAC,CAAA;IAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-plus",
3
- "version": "4.0.1",
3
+ "version": "4.2.0",
4
4
  "description": "Provides additional types for `typescript`.",
5
5
  "homepage": "https://github.com/unional/type-plus",
6
6
  "bugs": {
@@ -40,7 +40,8 @@
40
40
  "release": "npx semantic-release",
41
41
  "size-limit": "size-limit",
42
42
  "test": "jest",
43
- "verify": "run-p verify:build lint coverage",
43
+ "test:types": "tsc",
44
+ "verify": "run-p verify:build lint test:types coverage",
44
45
  "verify:build": "npm-run-all clean build --parallel dependency-check size-limit",
45
46
  "watch": "jest --watch"
46
47
  },
@@ -50,39 +51,39 @@
50
51
  }
51
52
  },
52
53
  "dependencies": {
53
- "tersify": "^3.8.0",
54
+ "tersify": "^3.8.2",
54
55
  "unpartial": "^0.6.4"
55
56
  },
56
57
  "devDependencies": {
57
- "@babel/core": "^7.16.7",
58
+ "@babel/core": "^7.17.7",
58
59
  "@babel/plugin-proposal-class-properties": "^7.16.7",
59
60
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
60
61
  "@babel/plugin-proposal-optional-chaining": "^7.16.7",
61
- "@babel/preset-env": "^7.16.7",
62
+ "@babel/preset-env": "^7.16.11",
62
63
  "@babel/preset-typescript": "^7.16.7",
63
- "@commitlint/cli": "^16.0.1",
64
- "@commitlint/config-conventional": "^16.0.0",
64
+ "@commitlint/cli": "^16.2.3",
65
+ "@commitlint/config-conventional": "^16.2.1",
65
66
  "@semantic-release/changelog": "^6.0.1",
66
- "@size-limit/preset-small-lib": "^7.0.5",
67
- "@types/jest": "^27.4.0",
68
- "@unional/fixture": "^1.7.2",
69
- "assertron": "^9.0.0",
67
+ "@size-limit/preset-small-lib": "^7.0.8",
68
+ "@types/jest": "^27.4.1",
69
+ "@unional/fixture": "^1.8.0",
70
+ "assertron": "^9.0.4",
70
71
  "dependency-check": "^4.1.0",
71
- "eslint": "^8.6.0",
72
+ "eslint": "^8.11.0",
72
73
  "eslint-plugin-harmony": "^6.0.0",
73
74
  "husky": "^7.0.4",
74
- "jest": "^27.4.5",
75
- "jest-progress-tracker": "^3.0.1",
76
- "jest-validate": "^27.4.2",
75
+ "jest": "^27.5.1",
76
+ "jest-progress-tracker": "^3.0.3",
77
+ "jest-validate": "^27.5.1",
77
78
  "jest-watch-repeat": "^2.0.0",
78
79
  "jest-watch-suspend": "^1.1.2",
79
80
  "jest-watch-toggle-config": "^2.0.1",
80
81
  "jest-watch-typeahead": "^1.0.0",
81
82
  "npm-run-all": "^4.1.5",
82
83
  "rimraf": "^3.0.2",
83
- "satisfier": "^5.1.1",
84
- "size-limit": "^7.0.5",
85
- "typescript": "^4.5.4"
84
+ "satisfier": "^5.1.2",
85
+ "size-limit": "^7.0.8",
86
+ "typescript": "^4.6.2"
86
87
  },
87
88
  "size-limit": [
88
89
  {
@@ -1,7 +1,10 @@
1
- import { IsPositive } from '../math'
2
-
3
- export type CreateTuple<L extends number, T = any> =
4
- IsPositive<L> extends true ? Device<[], L, T> : never
5
-
6
- type Device<R extends any[], L extends number, T> =
7
- R['length'] extends L ? R : Device<[T, ...R], L, T>
1
+ import { IsPositive } from '../math'
2
+
3
+ /**
4
+ * Creates `Tuple<T>` with `L` number of elements.
5
+ */
6
+ export type CreateTuple<L extends number, T = any> =
7
+ IsPositive<L> extends true ? Device<[], L, T> : never
8
+
9
+ type Device<R extends any[], L extends number, T> =
10
+ R['length'] extends L ? R : Device<[T, ...R], L, T>
@@ -0,0 +1,32 @@
1
+ import { AnyFunction, isType } from '..'
2
+ import { Last } from './Last'
3
+
4
+ test('any array', () => {
5
+ type A = Last<any[]>
6
+ isType.equal<true, any, A>()
7
+ })
8
+
9
+ test('never array', () => {
10
+ type A = Last<never[]>
11
+ isType.equal<true, never, A>()
12
+ })
13
+
14
+ test('typed array', () => {
15
+ type A = Last<string[]>
16
+ isType.equal<true, string, A>()
17
+ })
18
+
19
+ test('function array', () => {
20
+ type A = Last<AnyFunction[]>
21
+ isType.equal<true, AnyFunction, A>()
22
+ })
23
+
24
+ test('empty tuple gets undefined', () => {
25
+ type A = Last<[]>
26
+ isType.equal<true, undefined, A>()
27
+ })
28
+
29
+ test('tuple with function', () => {
30
+ type A = Last<[number, AnyFunction]>
31
+ isType.equal<true, AnyFunction, A>()
32
+ })
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Get the last type of an array or tuple.
3
+ */
4
+ export type Last<T extends any[]> = T extends [...any[], infer R] ? R : T[0]
@@ -1,32 +1,32 @@
1
- import { isType, Tail } from '..'
2
-
3
- test('get tail types', () => {
4
- type S = [1, 'a', 'b']
5
- type A = Tail<S>
6
-
7
- isType.equal<true, ['a', 'b'], A>()
8
- })
9
-
10
- test('empty tuple gets never', () => {
11
- type S = []
12
- type A = Tail<S>
13
-
14
- isType.equal<true, never, A>()
15
- })
16
-
17
- test('array gets same type', () => {
18
- type A = Tail<string[]>
19
-
20
- isType.equal<true, string[], A>()
21
- })
22
-
23
- test('union array', () => {
24
- type A = Tail<Array<string | boolean>>
25
-
26
- isType.equal<true, Array<string | boolean>, A>()
27
- })
28
-
29
- test('tuple with rest', () => {
30
- type A = Tail<[number, ...string[]]>
31
- isType.equal<true, string[], A>()
32
- })
1
+ import { isType, Tail } from '..'
2
+
3
+ test('get tail types', () => {
4
+ type S = [1, 'a', 'b']
5
+ type A = Tail<S>
6
+
7
+ isType.equal<true, ['a', 'b'], A>()
8
+ })
9
+
10
+ test('empty tuple gets never', () => {
11
+ type S = []
12
+ type A = Tail<S>
13
+
14
+ isType.equal<true, never, A>()
15
+ })
16
+
17
+ test('array gets same type', () => {
18
+ type A = Tail<string[]>
19
+
20
+ isType.equal<true, string[], A>()
21
+ })
22
+
23
+ test('union array', () => {
24
+ type A = Tail<Array<string | boolean>>
25
+
26
+ isType.equal<true, Array<string | boolean>, A>()
27
+ })
28
+
29
+ test('tuple with rest', () => {
30
+ type A = Tail<[number, ...string[]]>
31
+ isType.equal<true, string[], A>()
32
+ })
package/ts/array/Tail.ts CHANGED
@@ -1,7 +1,10 @@
1
- import { UnionOfValues } from './UnionOfValues'
2
-
3
- export type Tail<T extends any[]> = T['length'] extends 0
4
- ? never
5
- : (T extends [any, ...infer Tail]
6
- ? (Tail extends UnionOfValues<T>[] ? Tail : never)
7
- : T)
1
+ import { UnionOfValues } from './UnionOfValues'
2
+
3
+ /**
4
+ * Gets the types of a tuple except the first entry.
5
+ */
6
+ export type Tail<T extends any[]> = T['length'] extends 0
7
+ ? never
8
+ : (T extends [any, ...infer Tail]
9
+ ? (Tail extends UnionOfValues<T>[] ? Tail : never)
10
+ : T)
package/ts/array/index.ts CHANGED
@@ -9,6 +9,7 @@ export type { FindLast } from './FindLast'
9
9
  export type { Head } from './Head'
10
10
  export type { IntersectOfProps, MapToProp } from './IntersectOfProps'
11
11
  export type { IsArray } from './IsArray'
12
+ export type { Last } from './Last'
12
13
  export * from './literalArray'
13
14
  export type { PadLeft } from './PadLeft'
14
15
  export * from './reduceWhile'
package/ts/index.spec.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { T, types } from '.'
1
+ // import { T, types } from '.'
2
2
 
3
- test('export types also as T', () => {
4
- expect(T).toBe(types)
5
- })
3
+ // test('export types also as T', () => {
4
+ // expect(T).toBe(types)
5
+ // })
6
+
7
+ test.todo('no test')
@@ -1,49 +1,49 @@
1
- import { assertType, PartialExcept, PartialOmit, PartialPick } from '..'
2
-
3
- test('work on primitive type', () => {
4
- type Foo = PartialPick<number, 'toFixed'>
5
- const x: Foo = 1
6
- assertType<typeof x['toFixed']>(1 as unknown as 1['toFixed'] | undefined)
7
- })
8
-
9
- test('make picked properties optional', () => {
10
- type Foo = {
11
- a: number,
12
- b: number,
13
- c: number,
14
- }
15
-
16
- const y: PartialPick<Foo, 'a'> = { b: 1, c: 2 }
17
-
18
- y.a = undefined
19
- assertType.noUndefined(y.b)
20
- assertType.noUndefined(y.c)
21
- })
22
-
23
- test('make not specified properties optional', () => {
24
- type Foo = {
25
- a: number,
26
- b: number,
27
- c: number,
28
- }
29
-
30
- const y: PartialExcept<Foo, 'a'> = { a: 1 }
31
- assertType.noUndefined(y.a)
32
- y.b = undefined
33
- y.c = undefined
34
- })
35
-
36
-
37
- test('make not specified properties optional', () => {
38
- type Foo = {
39
- a: number,
40
- b: number,
41
- c: number,
42
- }
43
-
44
- const y: PartialOmit<Foo, 'a'> = { a: 1 }
45
-
46
- assertType.noUndefined(y.a)
47
- y.b = undefined
48
- y.c = undefined
49
- })
1
+ import { assertType, PartialExcept, PartialOmit, PartialPick } from '..'
2
+
3
+ test('work on primitive type', () => {
4
+ type Foo = PartialPick<number, 'toFixed'>
5
+ const x: Foo = 1
6
+ assertType<typeof x['toFixed']>(1 as unknown as 1['toFixed'] | undefined)
7
+ })
8
+
9
+ test('make picked properties optional', () => {
10
+ type Foo = {
11
+ a: number,
12
+ b: number,
13
+ c: number,
14
+ }
15
+
16
+ const y: PartialPick<Foo, 'a'> = { b: 1, c: 2 }
17
+
18
+ y.a = undefined
19
+ assertType.noUndefined(y.b)
20
+ assertType.noUndefined(y.c)
21
+ })
22
+
23
+ test('make not specified properties optional', () => {
24
+ type Foo = {
25
+ a: number,
26
+ b: number,
27
+ c: number,
28
+ }
29
+
30
+ const y: PartialExcept<Foo, 'a'> = { a: 1 }
31
+ assertType.noUndefined(y.a)
32
+ y.b = undefined
33
+ y.c = undefined
34
+ })
35
+
36
+
37
+ test('make not specified properties optional', () => {
38
+ type Foo = {
39
+ a: number,
40
+ b: number,
41
+ c: number,
42
+ }
43
+
44
+ const y: PartialOmit<Foo, 'a'> = { a: 1 }
45
+
46
+ assertType.noUndefined(y.a)
47
+ y.b = undefined
48
+ y.c = undefined
49
+ })
@@ -19,7 +19,7 @@ export * from './mapKey'
19
19
  export * from './mapProperties'
20
20
  export * from './omit'
21
21
  export type { OptionalKeys } from './OptionalKeys'
22
- export type { PartialOmit, PartialPick } from './Partial'
22
+ export type { PartialExcept, PartialOmit, PartialPick } from './Partial'
23
23
  export * from './pick'
24
24
  export type { RecursiveIntersect } from './RecursiveIntersect'
25
25
  export type { RecursivePartial } from './RecursivePartial'
@@ -29,7 +29,7 @@ export * from './replaceProperty'
29
29
  export type { RequiredExcept, RequiredPick } from './Required'
30
30
  export type { RequiredKeys } from './RequiredKeys'
31
31
  export * from './someKey'
32
+ export * from './split'
32
33
  export type { SpreadRecord } from './SpreadRecord'
33
34
  export * from './typeOverrideIncompatible'
34
35
  export type { ValueOf } from './ValueOf'
35
-
@@ -0,0 +1,54 @@
1
+ import { isType, split } from '..'
2
+
3
+ const target = { a: 0, b: '', c: false }
4
+ test('can use undefined as default', () => {
5
+ const [{ a }] = split(target, { a: undefined })
6
+
7
+ isType.equal<true, typeof a, number | undefined>()
8
+ expect(a).toBe(0)
9
+ })
10
+
11
+ test('can specify default with the same type', () => {
12
+ const [{ a }] = split(target, { a: 2 })
13
+
14
+ isType.equal<true, typeof a, number>()
15
+ expect(a).toBe(0)
16
+ })
17
+
18
+ test('can specify default as one of the intersect types', () => {
19
+ const [a] = split({ a: undefined as number | string | undefined }, { a: '2' })
20
+
21
+ isType.equal<true, typeof a, { a: number | string }>()
22
+ expect(a).toEqual({ a: '2' })
23
+ })
24
+
25
+ test('get remaining props in the last entry', () => {
26
+ const [, r] = split(target, { a: undefined })
27
+
28
+ isType.equal<true, typeof r, { b: string, c: boolean }>()
29
+ expect(r).toEqual({ b: '', c: false })
30
+ })
31
+
32
+ test('work with simple Record', () => {
33
+ const [a] = split({} as Record<string, string>, { a: 'a' })
34
+
35
+ isType.equal<true, typeof a, { a: string }>()
36
+ expect(a).toEqual({ a: 'a' })
37
+ })
38
+
39
+ test('can specify multiple splitters', () => {
40
+ const t = { r: 'r' } as { a?: string, b?: string, c?: string, r?: string }
41
+ const [a, b, c, r] = split(t,
42
+ { a: 'a' },
43
+ { b: 'b' },
44
+ { c: 'c' }
45
+ )
46
+ isType.equal<true, typeof a, { a: string }>()
47
+ isType.equal<true, typeof b, { b: string }>()
48
+ isType.equal<true, typeof c, { c: string }>()
49
+ isType.equal<true, typeof r, { r?: string | undefined }>()
50
+ expect(a).toEqual({ a: 'a' })
51
+ expect(b).toEqual({ b: 'b' })
52
+ expect(c).toEqual({ c: 'c' })
53
+ expect(r).toEqual({ r: 'r' })
54
+ })
@@ -0,0 +1,195 @@
1
+ import { AnyRecord, Omit, reduceByKey } from '..'
2
+
3
+ type Splitter<T extends AnyRecord> = Partial<{ [k in keyof T]: T[k] | undefined }>
4
+ type Split<T extends AnyRecord, S extends AnyRecord> = { [k in keyof S]: NonNullable<T[k]> | S[k] }
5
+
6
+ /**
7
+ * Split an object into multiple objects.
8
+ * @returns [...entries, remaining]
9
+ */
10
+ export function split<
11
+ T extends AnyRecord,
12
+ S1 extends Splitter<T>
13
+ >(target: T, split1: S1): [
14
+ Split<T, S1>,
15
+ Omit<T, keyof S1>
16
+ ]
17
+ export function split<
18
+ T extends AnyRecord,
19
+ S1 extends Splitter<T>,
20
+ S2 extends Splitter<T>,
21
+ >(target: T, split1: S1, split2: S2): [
22
+ Split<T, S1>,
23
+ Split<T, S2>,
24
+ Omit<T, keyof S1 | keyof S2>
25
+ ]
26
+ export function split<
27
+ T extends AnyRecord,
28
+ S1 extends Splitter<T>,
29
+ S2 extends Splitter<T>,
30
+ S3 extends Splitter<T>,
31
+ >(target: T, splitter1: S1, splitter2: S2, splitter3: S3): [
32
+ Split<T, S1>,
33
+ Split<T, S2>,
34
+ Split<T, S3>,
35
+ Omit<T, keyof S1 | keyof S2 | keyof S3>
36
+ ]
37
+ export function split<
38
+ T extends AnyRecord,
39
+ S1 extends Splitter<T>,
40
+ S2 extends Splitter<T>,
41
+ S3 extends Splitter<T>,
42
+ S4 extends Splitter<T>,
43
+ >(target: T,
44
+ splitter1: S1,
45
+ splitter2: S2,
46
+ splitter3: S3,
47
+ splitter4: S4,
48
+ ): [
49
+ Split<T, S1>,
50
+ Split<T, S2>,
51
+ Split<T, S3>,
52
+ Split<T, S4>,
53
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4>
54
+ ]
55
+ export function split<
56
+ T extends AnyRecord,
57
+ S1 extends Splitter<T>,
58
+ S2 extends Splitter<T>,
59
+ S3 extends Splitter<T>,
60
+ S4 extends Splitter<T>,
61
+ S5 extends Splitter<T>,
62
+ >(target: T,
63
+ splitter1: S1,
64
+ splitter2: S2,
65
+ splitter3: S3,
66
+ splitter4: S4,
67
+ splitter5: S5,
68
+ ): [
69
+ Split<T, S1>,
70
+ Split<T, S2>,
71
+ Split<T, S3>,
72
+ Split<T, S4>,
73
+ Split<T, S5>,
74
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5>
75
+ ]
76
+ export function split<
77
+ T extends AnyRecord,
78
+ S1 extends Splitter<T>,
79
+ S2 extends Splitter<T>,
80
+ S3 extends Splitter<T>,
81
+ S4 extends Splitter<T>,
82
+ S5 extends Splitter<T>,
83
+ S6 extends Splitter<T>,
84
+ >(target: T,
85
+ splitter1: S1,
86
+ splitter2: S2,
87
+ splitter3: S3,
88
+ splitter4: S4,
89
+ splitter5: S5,
90
+ splitter6: S6,
91
+ ): [
92
+ Split<T, S1>,
93
+ Split<T, S2>,
94
+ Split<T, S3>,
95
+ Split<T, S4>,
96
+ Split<T, S5>,
97
+ Split<T, S6>,
98
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6>
99
+ ]
100
+ export function split<
101
+ T extends AnyRecord,
102
+ S1 extends Splitter<T>,
103
+ S2 extends Splitter<T>,
104
+ S3 extends Splitter<T>,
105
+ S4 extends Splitter<T>,
106
+ S5 extends Splitter<T>,
107
+ S6 extends Splitter<T>,
108
+ S7 extends Splitter<T>,
109
+ >(target: T,
110
+ splitter1: S1,
111
+ splitter2: S2,
112
+ splitter3: S3,
113
+ splitter4: S4,
114
+ splitter5: S5,
115
+ splitter6: S6,
116
+ splitter7: S7,
117
+ ): [
118
+ Split<T, S1>,
119
+ Split<T, S2>,
120
+ Split<T, S3>,
121
+ Split<T, S4>,
122
+ Split<T, S5>,
123
+ Split<T, S6>,
124
+ Split<T, S7>,
125
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7>
126
+ ]
127
+ export function split<
128
+ T extends AnyRecord,
129
+ S1 extends Splitter<T>,
130
+ S2 extends Splitter<T>,
131
+ S3 extends Splitter<T>,
132
+ S4 extends Splitter<T>,
133
+ S5 extends Splitter<T>,
134
+ S6 extends Splitter<T>,
135
+ S7 extends Splitter<T>,
136
+ S8 extends Splitter<T>,
137
+ >(target: T,
138
+ splitter1: S1,
139
+ splitter2: S2,
140
+ splitter3: S3,
141
+ splitter4: S4,
142
+ splitter5: S5,
143
+ splitter6: S6,
144
+ splitter7: S7,
145
+ splitter8: S8,
146
+ ): [
147
+ Split<T, S1>,
148
+ Split<T, S2>,
149
+ Split<T, S3>,
150
+ Split<T, S4>,
151
+ Split<T, S5>,
152
+ Split<T, S6>,
153
+ Split<T, S7>,
154
+ Split<T, S8>,
155
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7 | keyof S8>
156
+ ]
157
+ export function split<
158
+ T extends AnyRecord,
159
+ S1 extends Splitter<T>,
160
+ S2 extends Splitter<T>,
161
+ S3 extends Splitter<T>,
162
+ S4 extends Splitter<T>,
163
+ S5 extends Splitter<T>,
164
+ S6 extends Splitter<T>,
165
+ S7 extends Splitter<T>,
166
+ S8 extends Splitter<T>,
167
+ S9 extends Splitter<T>,
168
+ >(target: T,
169
+ splitter1: S1,
170
+ splitter2: S2,
171
+ splitter3: S3,
172
+ splitter4: S4,
173
+ splitter5: S5,
174
+ splitter6: S6,
175
+ splitter7: S7,
176
+ splitter8: S8,
177
+ splitter9: S9,
178
+ ): [
179
+ Split<T, S1>,
180
+ Split<T, S2>,
181
+ Split<T, S3>,
182
+ Split<T, S4>,
183
+ Split<T, S5>,
184
+ Split<T, S6>,
185
+ Split<T, S7>,
186
+ Split<T, S8>,
187
+ Split<T, S9>,
188
+ Omit<T, keyof S1 | keyof S2 | keyof S3 | keyof S4 | keyof S5 | keyof S6 | keyof S7 | keyof S8 | keyof S9>
189
+ ]
190
+ export function split(target: AnyRecord, ...splitters: AnyRecord[]): AnyRecord[] {
191
+ const keyMap: AnyRecord = {}
192
+ const s = splitters.map(s => reduceByKey(s, (p, k) => (keyMap[k] = true, p[k] = target[k] ?? s[k], p), {} as AnyRecord))
193
+ const r = reduceByKey(target, (p, k) => keyMap[k] ? p : (p[k] = target[k], p), {} as AnyRecord)
194
+ return [...s, r]
195
+ }