type-plus 4.5.2 → 4.6.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.
package/README.md CHANGED
@@ -285,12 +285,14 @@ type No = IsAny<1, 'yes', 'no'> // 'no'
285
285
  - `CreateTuple<L, T>`: Creates `Tuple<T>` with `L` number of elements.
286
286
  - `DropFirst<A>`: drops the first value type of `A`.
287
287
  - `DropLast<A>`: drops the last value type of `A`.
288
- - `Filter<A, Criteria>`: gets the array of types satisfying `Criteria` in `A`.
288
+ - `DropMatch<A, Criteria>`: drops entries matching `Criteria` in array or tuple `A`.
289
+ - `Filter<A, Criteria>`: filter the array or tuple `A`, keeping entries satisfying `Criteria`. **deprecated. Renaming to `KeepMatch`**
289
290
  - `FindFirst<A, Criteria>`: gets the first type satisfying `Criteria`.
290
291
  - `FindLast<A, Criteria>`: gets the last type satisfying `Criteria`.
291
292
  - `Head<A>`: gets the first entry in the array.
292
293
  - `IntersectOfProps<A, K>`: gets the intersect of `A[K]` types (deprecate `MapToProp`)
293
294
  - `IsArray<T>`: `logical` predicate for `Array`.
295
+ - `KeepMatch<A, Criteria>`: keeps entries satisfying `Criteria` in array or tuple `A`.
294
296
  - `Last<A>`: gets the last type of an array or tuple.
295
297
  - `literalArray(...entries)`: return an array whose items are restricted to the provided literals.
296
298
  - `PadLeft<A, Total, PadWith>`: pads `A` with `PadWith` if the length of `A` is less than `L`.
@@ -0,0 +1,5 @@
1
+ import { Equal } from '../predicates';
2
+ declare type ExcludeUnionOfEmptyTuple<A> = Equal<A, []> extends true ? A : Exclude<A, []>;
3
+ export declare type DropMatch<A extends Array<any>, Criteria> = number extends A['length'] ? (A[0] extends Criteria ? never[] : (undefined extends Criteria ? Array<NonNullable<A[0]>> : (Criteria extends A[0] ? Array<Exclude<A[0], Criteria>> : A))) : DropMatchTuple<A, Criteria>;
4
+ declare type DropMatchTuple<A extends Array<any>, Criteria> = (A['length'] extends 0 ? A : (A extends [infer Head, ...infer Tail] ? (Tail['length'] extends 0 ? (undefined extends Criteria ? (Head extends Criteria ? [] : [Head]) : ExcludeUnionOfEmptyTuple<(Head extends Criteria ? [] : [Head])>) : (Exclude<Head, Criteria> extends never ? DropMatch<Tail, Criteria> : [Exclude<Head, Criteria>, ...DropMatch<Tail, Criteria>])) : never[]));
5
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=DropMatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropMatch.js","sourceRoot":"","sources":["../../ts/array/DropMatch.ts"],"names":[],"mappings":""}
@@ -1 +1,2 @@
1
1
  export declare type Filter<A extends Array<any>, Criteria> = number extends A['length'] ? (A[0] extends Criteria ? A : (Criteria extends A[0] ? Array<Criteria> : never[])) : (A['length'] extends 0 ? never : (A extends [infer Head, ...infer Tail] ? (Tail['length'] extends 0 ? (Head extends Criteria ? [Head] : never[]) : (Head extends Criteria ? [Head, ...Filter<Tail, Criteria>] : Filter<Tail, Criteria>)) : never));
2
+ export declare type KeepMatch<A extends Array<any>, Criteria> = Filter<A, Criteria>;
@@ -3,7 +3,8 @@ export type { Concat } from './Concat';
3
3
  export type { CreateTuple } from './CreateTuple';
4
4
  export type { DropFirst } from './DropFirst';
5
5
  export type { DropLast } from './DropLast';
6
- export type { Filter } from './Filter';
6
+ export type { DropMatch } from './DropMatch';
7
+ export type { Filter, KeepMatch } from './Filter';
7
8
  export type { FindFirst, First } from './FindFirst';
8
9
  export type { FindLast } from './FindLast';
9
10
  export type { Head } from './Head';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAYA,iDAA8B;AAE9B,gDAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAaA,iDAA8B;AAE9B,gDAA6B"}
@@ -3,29 +3,29 @@ import { And } from '../predicates';
3
3
  import { IsPositive } from './IsPositive';
4
4
  import { IsWhole } from './IsWhole';
5
5
  export declare namespace Digit {
6
- type ToTuple = {
6
+ type ToTuple<T = 1> = {
7
7
  [k in number]: any[];
8
8
  } & {
9
9
  0: [];
10
- 1: [1];
11
- 2: [1, 1];
12
- 3: [1, 1, 1];
13
- 4: [1, 1, 1, 1];
14
- 5: [1, 1, 1, 1, 1];
15
- 6: [1, 1, 1, 1, 1, 1];
16
- 7: [1, 1, 1, 1, 1, 1, 1];
17
- 8: [1, 1, 1, 1, 1, 1, 1, 1];
18
- 9: [1, 1, 1, 1, 1, 1, 1, 1, 1];
19
- 10: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
20
- 11: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
21
- 12: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
22
- 13: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
23
- 14: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
24
- 15: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
25
- 16: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
26
- 17: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
27
- 18: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
28
- 19: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
10
+ 1: [T];
11
+ 2: [T, T];
12
+ 3: [T, T, T];
13
+ 4: [T, T, T, T];
14
+ 5: [T, T, T, T, T];
15
+ 6: [T, T, T, T, T, T];
16
+ 7: [T, T, T, T, T, T, T];
17
+ 8: [T, T, T, T, T, T, T, T];
18
+ 9: [T, T, T, T, T, T, T, T, T];
19
+ 10: [T, T, T, T, T, T, T, T, T, T];
20
+ 11: [T, T, T, T, T, T, T, T, T, T, T];
21
+ 12: [T, T, T, T, T, T, T, T, T, T, T, T];
22
+ 13: [T, T, T, T, T, T, T, T, T, T, T, T, T];
23
+ 14: [T, T, T, T, T, T, T, T, T, T, T, T, T, T];
24
+ 15: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
25
+ 16: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
26
+ 17: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
27
+ 18: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
28
+ 19: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
29
29
  };
30
30
  type GreaterThan<A extends number, B extends number> = B extends GreaterThanMap[A] ? true : false;
31
31
  type GreaterThanMap = {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=DropMatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropMatch.js","sourceRoot":"","sources":["../../ts/array/DropMatch.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":"AAYA,cAAc,gBAAgB,CAAA;AAE9B,cAAc,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/array/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAA;AAE9B,cAAc,eAAe,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-plus",
3
- "version": "4.5.2",
3
+ "version": "4.6.0",
4
4
  "description": "Provides additional types for TypeScript.",
5
5
  "homepage": "https://github.com/unional/type-plus",
6
6
  "bugs": {
@@ -1,4 +1,12 @@
1
- import { IsPositive } from '../math'
1
+ import {
2
+ // Digit,
3
+ IsPositive
4
+ } from '../math'
5
+
6
+ // export type CreateTuple<L extends number, T = any> =
7
+ // number extends L ? T[] : IsPositive<L> extends true
8
+ // ? [...Digit.ToTuple<T>[L]]
9
+ // : never
2
10
 
3
11
  type BuildPowersOf2LengthArrays<N extends number, R extends never[][]> =
4
12
  R[0][N] extends never ? R : BuildPowersOf2LengthArrays<N, [[...R[0], ...R[0]], ...R]>
@@ -0,0 +1,113 @@
1
+ import { DropMatch, isType } from '..'
2
+
3
+ describe('DropMatch<A, C>', () => {
4
+ describe('A is array', () => {
5
+ test('drop all types gets never[]', () => {
6
+ type A = DropMatch<Array<string>, string>
7
+ isType.equal<true, never[], A>()
8
+
9
+ type B = DropMatch<Array<string | boolean>, string | boolean>
10
+ isType.equal<true, never[], B>()
11
+ })
12
+
13
+ test('drop undefined and null from array', () => {
14
+ type A = DropMatch<Array<string | undefined>, undefined>
15
+ isType.equal<true, string[], A>()
16
+
17
+ type B = DropMatch<Array<string | number | undefined>, undefined>
18
+ isType.equal<true, Array<string | number>, B>()
19
+
20
+ type C = DropMatch<Array<string | number | undefined | null>, undefined | null>
21
+ isType.equal<true, Array<string | number>, C>()
22
+ })
23
+
24
+ test('can get undefined and null array when other types dropped', () => {
25
+ type A = DropMatch<Array<string | undefined>, string>
26
+ isType.equal<true, undefined[], A>()
27
+
28
+ type B = DropMatch<Array<string | number | null>, string>
29
+ isType.equal<true, Array<number | null>, B>()
30
+ })
31
+
32
+ test('unmatched criteria returns original', () => {
33
+ type Actual = DropMatch<Array<string | undefined>, number>
34
+
35
+ isType.equal<true, Array<string | undefined>, Actual>()
36
+ })
37
+ })
38
+
39
+ describe('A is Tuple', () => {
40
+ test('empty tuple', () => {
41
+ type A = DropMatch<[], undefined>
42
+ isType.equal<true, [], A>()
43
+
44
+ type B = DropMatch<[1, undefined], undefined>
45
+ isType.equal<true, [1], B>()
46
+
47
+ type C = DropMatch<[1, undefined, 3], undefined>
48
+ isType.equal<true, [1, 3], C>()
49
+
50
+ type D = DropMatch<[1, string | undefined, 3], undefined>
51
+ isType.equal<true, [1, string, 3], D>()
52
+ })
53
+
54
+ test('drop undefined from tuple', () => {
55
+ type A = DropMatch<[undefined], undefined>
56
+ isType.equal<true, [], A>()
57
+
58
+ type B = DropMatch<[1, undefined], undefined>
59
+ isType.equal<true, [1], B>()
60
+
61
+ type C = DropMatch<[1, undefined, 3], undefined>
62
+ isType.equal<true, [1, 3], C>()
63
+
64
+ type D = DropMatch<[1, string | undefined, 3], undefined>
65
+ isType.equal<true, [1, string, 3], D>()
66
+ })
67
+
68
+ test('get original if not matched', () => {
69
+ type A = DropMatch<[1], undefined>
70
+ isType.equal<true, [1], A>()
71
+
72
+ type B = DropMatch<[1], undefined | string>
73
+ isType.equal<true, [1], B>()
74
+
75
+ type C = DropMatch<[1, 2, 3, 4], 5>
76
+ isType.equal<true, [1, 2, 3, 4], C>()
77
+ })
78
+
79
+ test('drop narrow type', () => {
80
+ type C = DropMatch<[1], number>
81
+ isType.equal<true, [], C>()
82
+ })
83
+
84
+ test('keep widen type', () => {
85
+ type D = DropMatch<[number], 1>
86
+ isType.equal<true, [number], D>()
87
+ })
88
+
89
+ test('drop type from tuple', () => {
90
+ type A = DropMatch<[1], 1>
91
+ isType.equal<true, [], A>()
92
+
93
+ type B = DropMatch<[number | string], number>
94
+ isType.equal<true, [string], B>()
95
+
96
+ type C = DropMatch<[1, undefined, 3], 1>
97
+ isType.equal<true, [undefined, 3], C>()
98
+
99
+ type D = DropMatch<[1, string | undefined, 3], 3>
100
+ isType.equal<true, [1, string | undefined], D>()
101
+ })
102
+
103
+ test('drop multiple types', () => {
104
+ type Actual = DropMatch<[1, 2, 3, 4], 2 | 4>
105
+ isType.equal<true, [1, 3], Actual>()
106
+ })
107
+
108
+ test('drop undefined and null', () => {
109
+ type Actual = DropMatch<[1, undefined, 3, null], undefined | null>
110
+ isType.equal<true, [1, 3], Actual>()
111
+ })
112
+ })
113
+ })
@@ -0,0 +1,53 @@
1
+ import { Equal } from '../predicates'
2
+
3
+ type ExcludeUnionOfEmptyTuple<A> = Equal<A, []> extends true ? A : Exclude<A, []>
4
+
5
+ /**
6
+ * drops entries matching `Criteria` in array or tuple `A`.
7
+ */
8
+ export type DropMatch<A extends Array<any>, Criteria> =
9
+ number extends A['length']
10
+ // array
11
+ ? (A[0] extends Criteria
12
+ // criteria matches: DropAll<string[], string>
13
+ ? never[]
14
+ : (undefined extends Criteria
15
+ ? Array<NonNullable<A[0]>>
16
+ // TODO: A[0] extends Criteria?
17
+ : (Criteria extends A[0] ? Array<Exclude<A[0], Criteria>> : A))
18
+ )
19
+ : DropMatchTuple<A, Criteria>
20
+
21
+ type DropMatchTuple<A extends Array<any>, Criteria> =
22
+ (A['length'] extends 0
23
+ // empty tuple
24
+ ? A
25
+ : (A extends [infer Head, ...infer Tail]
26
+ ? (Tail['length'] extends 0
27
+ // single element tuple
28
+ ? (undefined extends Criteria
29
+ ? (Head extends Criteria
30
+ ? []
31
+ : [Head])
32
+ : ExcludeUnionOfEmptyTuple<(Head extends Criteria ? [] : [Head])>
33
+ )
34
+ // multiple elements
35
+ : (Exclude<Head, Criteria> extends never
36
+ ? DropMatch<Tail, Criteria>
37
+ : [Exclude<Head, Criteria>, ...DropMatch<Tail, Criteria>]
38
+ ))
39
+ : never[]))
40
+ // : (undefined extends Criteria
41
+ // ? (Head extends undefined
42
+ // ? DropAll<Tail, Criteria>
43
+ // : [NonNullable<Head>, ...DropAll<Tail, Criteria>])
44
+ // : []
45
+ // ))
46
+ // : (Head extends Criteria
47
+ // ? (undefined extends Criteria
48
+ // ? [1, 2, 3]// [NonNullable<Head>, ...Filter<Tail, Criteria>]
49
+ // : [2, 3]// [Head, ...Filter<Tail, Criteria>]
50
+ // )
51
+ // : [2]//Filter<Tail, Criteria>
52
+ // ))
53
+ // : 2[]))
@@ -1,4 +1,4 @@
1
- import { Filter, isType } from '..'
1
+ import { Filter, isType, KeepMatch } from '..'
2
2
 
3
3
  describe('Filter<A, C>', () => {
4
4
  describe('A is array', () => {
@@ -52,3 +52,56 @@ describe('Filter<A, C>', () => {
52
52
  })
53
53
  })
54
54
  })
55
+
56
+ describe('KeepMatch<A, C>', () => {
57
+ describe('A is array', () => {
58
+ test('array matching criteria gets itself', () => {
59
+ type Actual = KeepMatch<string[], string>
60
+ isType.equal<true, string[], Actual>()
61
+ })
62
+
63
+ test('array not matching criteria gets never[]', () => {
64
+ type Actual = KeepMatch<string[], number>
65
+ isType.equal<true, never[], Actual>()
66
+ })
67
+
68
+ test('remove unmatched type form array', () => {
69
+ type Actual = KeepMatch<Array<string | number>, string>
70
+
71
+ isType.equal<true, string[], Actual>()
72
+ })
73
+
74
+ test('remove undefined and null', () => {
75
+ type Actual = KeepMatch<Array<string | undefined | null>, string>
76
+ isType.equal<true, string[], Actual>()
77
+ })
78
+
79
+ test('can filter with undefined and null', () => {
80
+ type Actual = KeepMatch<Array<string | undefined | null>, undefined | null>
81
+ // Array<undefined | null> is destructured to undefined[] | null[] by TypeScript
82
+ isType.equal<true, undefined[] | null[], Actual>()
83
+ })
84
+
85
+ test('work with never[]', () => {
86
+ type Actual = KeepMatch<never[], undefined>
87
+ isType.equal<true, never[], Actual>()
88
+ })
89
+ })
90
+
91
+ describe(`A is Tuple`, () => {
92
+ test('matching criteria', () => {
93
+ type Actual = KeepMatch<[1, 2, 3, 4], 2 | 4>
94
+ isType.equal<true, [2, 4], Actual>()
95
+ })
96
+
97
+ test('no match gets never[]', () => {
98
+ type Actual = KeepMatch<[1, 2, 3, 4], 5>
99
+ isType.equal<true, never[], Actual>()
100
+ })
101
+
102
+ test('matching undefined and null', () => {
103
+ type Actual = KeepMatch<[1, undefined, 3, null], undefined | null>
104
+ isType.equal<true, [undefined, null], Actual>()
105
+ })
106
+ })
107
+ })
@@ -1,3 +1,7 @@
1
+ /**
2
+ * filter the array or tuple `A`, keeping entries satisfying `Criteria`.
3
+ * @deprecated renaming to `KeepMatch`
4
+ */
1
5
  export type Filter<A extends Array<any>, Criteria> =
2
6
  number extends A['length']
3
7
  // array
@@ -15,3 +19,8 @@ export type Filter<A extends Array<any>, Criteria> =
15
19
  ? [Head, ...Filter<Tail, Criteria>]
16
20
  : Filter<Tail, Criteria>))
17
21
  : never))
22
+
23
+ /**
24
+ * keeps entries satisfying `Criteria` in array or tuple `A`.
25
+ */
26
+ export type KeepMatch<A extends Array<any>, Criteria> = Filter<A, Criteria>
package/ts/array/index.ts CHANGED
@@ -3,7 +3,8 @@ export type { Concat } from './Concat'
3
3
  export type { CreateTuple } from './CreateTuple'
4
4
  export type { DropFirst } from './DropFirst'
5
5
  export type { DropLast } from './DropLast'
6
- export type { Filter } from './Filter'
6
+ export type { DropMatch } from './DropMatch'
7
+ export type { Filter, KeepMatch } from './Filter'
7
8
  export type { FindFirst, First } from './FindFirst'
8
9
  export type { FindLast } from './FindLast'
9
10
  export type { Head } from './Head'
package/ts/math/Digit.ts CHANGED
@@ -4,29 +4,29 @@ import { IsPositive } from './IsPositive'
4
4
  import { IsWhole } from './IsWhole'
5
5
 
6
6
  export namespace Digit {
7
- export type ToTuple = {
7
+ export type ToTuple<T = 1> = {
8
8
  [k in number]: any[]
9
9
  } & {
10
10
  0: [],
11
- 1: [1],
12
- 2: [1, 1],
13
- 3: [1, 1, 1],
14
- 4: [1, 1, 1, 1],
15
- 5: [1, 1, 1, 1, 1],
16
- 6: [1, 1, 1, 1, 1, 1],
17
- 7: [1, 1, 1, 1, 1, 1, 1],
18
- 8: [1, 1, 1, 1, 1, 1, 1, 1],
19
- 9: [1, 1, 1, 1, 1, 1, 1, 1, 1],
20
- 10: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
21
- 11: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
22
- 12: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
23
- 13: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
24
- 14: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
25
- 15: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
26
- 16: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
27
- 17: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
28
- 18: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
29
- 19: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
11
+ 1: [T],
12
+ 2: [T, T],
13
+ 3: [T, T, T],
14
+ 4: [T, T, T, T],
15
+ 5: [T, T, T, T, T],
16
+ 6: [T, T, T, T, T, T],
17
+ 7: [T, T, T, T, T, T, T],
18
+ 8: [T, T, T, T, T, T, T, T],
19
+ 9: [T, T, T, T, T, T, T, T, T],
20
+ 10: [T, T, T, T, T, T, T, T, T, T],
21
+ 11: [T, T, T, T, T, T, T, T, T, T, T],
22
+ 12: [T, T, T, T, T, T, T, T, T, T, T, T],
23
+ 13: [T, T, T, T, T, T, T, T, T, T, T, T, T],
24
+ 14: [T, T, T, T, T, T, T, T, T, T, T, T, T, T],
25
+ 15: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T],
26
+ 16: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T],
27
+ 17: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T],
28
+ 18: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T],
29
+ 19: [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T],
30
30
  }
31
31
 
32
32
  /**