type-plus 4.5.0 → 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 +3 -1
- package/cjs/ComposableTypes.d.ts +0 -6
- package/cjs/JSONTypes.js +0 -1
- package/cjs/JSONTypes.js.map +1 -1
- package/cjs/UnionKeys.d.ts +0 -4
- package/cjs/array/CommonPropKeys.d.ts +0 -7
- package/cjs/array/CreateTuple.d.ts +10 -8
- package/cjs/array/DropMatch.d.ts +5 -0
- package/cjs/array/DropMatch.js +3 -0
- package/cjs/array/DropMatch.js.map +1 -0
- package/cjs/array/Filter.d.ts +2 -1
- package/cjs/array/FindFirst.d.ts +0 -3
- package/cjs/array/IntersectOfProps.d.ts +0 -7
- package/cjs/array/Last.d.ts +0 -3
- package/cjs/array/Tail.d.ts +0 -3
- package/cjs/array/UnionOfProps.d.ts +0 -7
- package/cjs/array/UnionOfValues.d.ts +0 -7
- package/cjs/array/index.d.ts +2 -1
- package/cjs/array/index.js.map +1 -1
- package/cjs/assertion/assertType.d.ts +0 -4
- package/cjs/assertion/assertType.js +0 -8
- package/cjs/assertion/assertType.js.map +1 -1
- package/cjs/functional/ChainFn.d.ts +0 -3
- package/cjs/functional/compose.d.ts +0 -3
- package/cjs/functional/compose.js +0 -3
- package/cjs/functional/compose.js.map +1 -1
- package/cjs/index.js +0 -2
- package/cjs/index.js.map +1 -1
- package/cjs/math/Add.d.ts +0 -6
- package/cjs/math/Digit.d.ts +20 -23
- package/cjs/math/IsPositive.d.ts +0 -5
- package/cjs/math/IsWhole.d.ts +0 -5
- package/cjs/math/Subtract.d.ts +0 -3
- package/cjs/nodejs/isNodeError.d.ts +0 -5
- package/cjs/nodejs/isNodeError.js +0 -5
- package/cjs/nodejs/isNodeError.js.map +1 -1
- package/cjs/nominal-types/Brand.d.ts +0 -10
- package/cjs/nominal-types/Brand.js +0 -3
- package/cjs/nominal-types/Brand.js.map +1 -1
- package/cjs/nominal-types/Flavor.d.ts +0 -12
- package/cjs/nominal-types/Flavor.js +0 -3
- package/cjs/nominal-types/Flavor.js.map +1 -1
- package/cjs/object/ExcludePropType.d.ts +0 -3
- package/cjs/object/IsDisjoint.d.ts +0 -4
- package/cjs/object/KeyTypes.d.ts +0 -5
- package/cjs/object/KeyofOptional.d.ts +0 -3
- package/cjs/object/KnownKeys.js +0 -3
- package/cjs/object/KnownKeys.js.map +1 -1
- package/cjs/object/Partial.d.ts +0 -9
- package/cjs/object/RecursiveIntersect.d.ts +0 -11
- package/cjs/object/Required.js +0 -1
- package/cjs/object/Required.js.map +1 -1
- package/cjs/object/facade.d.ts +0 -3
- package/cjs/object/facade.js +0 -3
- package/cjs/object/facade.js.map +1 -1
- package/cjs/object/mapProperties.d.ts +0 -8
- package/cjs/object/mapProperties.js +0 -8
- package/cjs/object/mapProperties.js.map +1 -1
- package/cjs/object/omit.d.ts +0 -3
- package/cjs/object/pick.d.ts +0 -7
- package/cjs/object/record.d.ts +0 -3
- package/cjs/object/record.js +0 -3
- package/cjs/object/record.js.map +1 -1
- package/cjs/object/reduceKey.d.ts +0 -3
- package/cjs/object/reduceKey.js +0 -3
- package/cjs/object/reduceKey.js.map +1 -1
- package/cjs/object/split.d.ts +0 -4
- package/cjs/predicates/CanAssign.d.ts +0 -3
- package/cjs/predicates/Equal.d.ts +0 -6
- package/cjs/predicates/isType.js +0 -6
- package/cjs/predicates/isType.js.map +1 -1
- package/cjs/promise/PromiseValue.d.ts +0 -3
- package/cjs/promise/PromiseValueMerge.d.ts +0 -3
- package/cjs/promise/isPromise.js +0 -1
- package/cjs/promise/isPromise.js.map +1 -1
- package/cjs/utils/Widen.d.ts +0 -4
- package/esm/JSONTypes.js +0 -1
- package/esm/JSONTypes.js.map +1 -1
- package/esm/array/DropMatch.js +2 -0
- package/esm/array/DropMatch.js.map +1 -0
- package/esm/array/index.js.map +1 -1
- package/esm/assertion/assertType.js +0 -8
- package/esm/assertion/assertType.js.map +1 -1
- package/esm/functional/compose.js +0 -3
- package/esm/functional/compose.js.map +1 -1
- package/esm/index.js +0 -2
- package/esm/index.js.map +1 -1
- package/esm/nodejs/isNodeError.js +0 -5
- package/esm/nodejs/isNodeError.js.map +1 -1
- package/esm/nominal-types/Brand.js +0 -3
- package/esm/nominal-types/Brand.js.map +1 -1
- package/esm/nominal-types/Flavor.js +0 -3
- package/esm/nominal-types/Flavor.js.map +1 -1
- package/esm/object/KnownKeys.js +0 -3
- package/esm/object/KnownKeys.js.map +1 -1
- package/esm/object/Required.js +0 -1
- package/esm/object/Required.js.map +1 -1
- package/esm/object/facade.js +0 -3
- package/esm/object/facade.js.map +1 -1
- package/esm/object/mapProperties.js +0 -8
- package/esm/object/mapProperties.js.map +1 -1
- package/esm/object/record.js +0 -3
- package/esm/object/record.js.map +1 -1
- package/esm/object/reduceKey.js +0 -3
- package/esm/object/reduceKey.js.map +1 -1
- package/esm/predicates/isType.js +0 -6
- package/esm/predicates/isType.js.map +1 -1
- package/esm/promise/isPromise.js +0 -1
- package/esm/promise/isPromise.js.map +1 -1
- package/package.json +1 -1
- package/ts/array/CreateTuple.spec.ts +32 -21
- package/ts/array/CreateTuple.ts +30 -7
- package/ts/array/DropMatch.spec.ts +113 -0
- package/ts/array/DropMatch.ts +53 -0
- package/ts/array/Filter.spec.ts +107 -21
- package/ts/array/Filter.ts +26 -12
- package/ts/array/index.ts +2 -1
- package/ts/math/Add.spec.ts +82 -82
- package/ts/math/Digit.spec.ts +184 -185
- package/ts/math/Digit.ts +20 -20
package/ts/array/CreateTuple.ts
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
|
-
import
|
|
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
|
|
10
|
+
|
|
11
|
+
type BuildPowersOf2LengthArrays<N extends number, R extends never[][]> =
|
|
12
|
+
R[0][N] extends never ? R : BuildPowersOf2LengthArrays<N, [[...R[0], ...R[0]], ...R]>
|
|
13
|
+
|
|
14
|
+
type ConcatLargestUntilDone<N extends number, R extends never[][], B extends never[]> =
|
|
15
|
+
B['length'] extends N ? B : [...R[0], ...B][N] extends never
|
|
16
|
+
? ConcatLargestUntilDone<N, R extends [R[0], ...infer U] ? U extends never[][] ? U : never : never, B>
|
|
17
|
+
: ConcatLargestUntilDone<N, R extends [R[0], ...infer U] ? U extends never[][] ? U : never : never, [...R[0], ...B]>
|
|
18
|
+
|
|
19
|
+
type Replace<R extends any[], T> = { [K in keyof R]: T }
|
|
2
20
|
|
|
3
21
|
/**
|
|
4
22
|
* Creates `Tuple<T>` with `L` number of elements.
|
|
23
|
+
* @note The original implementation hits recursive limit.
|
|
24
|
+
* Updated implementation based on below by @lazytype
|
|
25
|
+
* @see https://github.com/microsoft/TypeScript/issues/26223#issuecomment-674514787
|
|
26
|
+
* @see https://github.com/microsoft/TypeScript/issues/47874#issuecomment-1039157322
|
|
5
27
|
*/
|
|
6
28
|
export type CreateTuple<L extends number, T = any> =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
29
|
+
number extends L ? T[] : IsPositive<L> extends true
|
|
30
|
+
? {
|
|
31
|
+
[K in L]: BuildPowersOf2LengthArrays<K, [[never]]> extends infer U
|
|
32
|
+
? (U extends never[][] ? Replace<ConcatLargestUntilDone<K, U, []>, T> : never)
|
|
33
|
+
: never
|
|
34
|
+
}[L]
|
|
35
|
+
: never
|
|
@@ -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[]))
|
package/ts/array/Filter.spec.ts
CHANGED
|
@@ -1,21 +1,107 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
import { Filter, isType, KeepMatch } from '..'
|
|
2
|
+
|
|
3
|
+
describe('Filter<A, C>', () => {
|
|
4
|
+
describe('A is array', () => {
|
|
5
|
+
test('array matching criteria gets itself', () => {
|
|
6
|
+
type Actual = Filter<string[], string>
|
|
7
|
+
isType.equal<true, string[], Actual>()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test('array not matching criteria gets never[]', () => {
|
|
11
|
+
type Actual = Filter<string[], number>
|
|
12
|
+
isType.equal<true, never[], Actual>()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('remove unmatched type form array', () => {
|
|
16
|
+
type Actual = Filter<Array<string | number>, string>
|
|
17
|
+
|
|
18
|
+
isType.equal<true, string[], Actual>()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('remove undefined and null', () => {
|
|
22
|
+
type Actual = Filter<Array<string | undefined | null>, string>
|
|
23
|
+
isType.equal<true, string[], Actual>()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('can filter with undefined and null', () => {
|
|
27
|
+
type Actual = Filter<Array<string | undefined | null>, undefined | null>
|
|
28
|
+
// Array<undefined | null> is destructured to undefined[] | null[] by TypeScript
|
|
29
|
+
isType.equal<true, undefined[] | null[], Actual>()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('work with never[]', () => {
|
|
33
|
+
type Actual = Filter<never[], undefined>
|
|
34
|
+
isType.equal<true, never[], Actual>()
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe(`A is Tuple`, () => {
|
|
39
|
+
test('matching criteria', () => {
|
|
40
|
+
type Actual = Filter<[1, 2, 3, 4], 2 | 4>
|
|
41
|
+
isType.equal<true, [2, 4], Actual>()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('no match gets never[]', () => {
|
|
45
|
+
type Actual = Filter<[1, 2, 3, 4], 5>
|
|
46
|
+
isType.equal<true, never[], Actual>()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('matching undefined and null', () => {
|
|
50
|
+
type Actual = Filter<[1, undefined, 3, null], undefined | null>
|
|
51
|
+
isType.equal<true, [undefined, null], Actual>()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
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
|
+
})
|
package/ts/array/Filter.ts
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
/**
|
|
2
|
+
* filter the array or tuple `A`, keeping entries satisfying `Criteria`.
|
|
3
|
+
* @deprecated renaming to `KeepMatch`
|
|
4
|
+
*/
|
|
5
|
+
export type Filter<A extends Array<any>, Criteria> =
|
|
6
|
+
number extends A['length']
|
|
7
|
+
// array
|
|
8
|
+
? (A[0] extends Criteria
|
|
9
|
+
? A
|
|
10
|
+
: (Criteria extends A[0] ? Array<Criteria> : never[])
|
|
11
|
+
)
|
|
12
|
+
// tuple
|
|
13
|
+
: (A['length'] extends 0
|
|
14
|
+
? never
|
|
15
|
+
: (A extends [infer Head, ...infer Tail]
|
|
16
|
+
? (Tail['length'] extends 0
|
|
17
|
+
? (Head extends Criteria ? [Head] : never[])
|
|
18
|
+
: (Head extends Criteria
|
|
19
|
+
? [Head, ...Filter<Tail, Criteria>]
|
|
20
|
+
: Filter<Tail, Criteria>))
|
|
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 {
|
|
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/Add.spec.ts
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
import { Add, Increment, isType } from '..'
|
|
2
|
-
|
|
3
|
-
describe('Add<A, B>', () => {
|
|
4
|
-
test('fractional A gets never', () => {
|
|
5
|
-
isType.equal<true, never, Add<1.1, 1>>()
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
test('negative A gets never', () => {
|
|
9
|
-
isType.equal<true, never, Add<-1, 1>>()
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
test('fractional B gets never', () => {
|
|
13
|
-
isType.equal<true, never, Add<1, 1.2>>()
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test('negative B gets never', () => {
|
|
17
|
-
isType.equal<true, never, Add<1, -1>>()
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
test('number gets Fail', () => {
|
|
21
|
-
isType.equal<true, never, Add<number, 1>>()
|
|
22
|
-
isType.equal<true, never, Add<1, number>>()
|
|
23
|
-
|
|
24
|
-
isType.equal<true, number, Add<number, 1, number>>()
|
|
25
|
-
isType.equal<true, number, Add<1, number, number>>()
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
describe('single digit', () => {
|
|
29
|
-
test('0 + n = n', () => {
|
|
30
|
-
isType.equal<true, 0, Add<0, 0>>()
|
|
31
|
-
isType.equal<true, 1, Add<0, 1>>()
|
|
32
|
-
isType.equal<true, 2, Add<0, 2>>()
|
|
33
|
-
isType.equal<true, 3, Add<0, 3>>()
|
|
34
|
-
isType.equal<true, 4, Add<0, 4>>()
|
|
35
|
-
isType.equal<true, 5, Add<0, 5>>()
|
|
36
|
-
isType.equal<true, 6, Add<0, 6>>()
|
|
37
|
-
isType.equal<true, 7, Add<0, 7>>()
|
|
38
|
-
isType.equal<true, 8, Add<0, 8>>()
|
|
39
|
-
isType.equal<true, 9, Add<0, 9>>()
|
|
40
|
-
})
|
|
41
|
-
test('9 + n', () => {
|
|
42
|
-
isType.equal<true, 9, Add<9, 0>>()
|
|
43
|
-
isType.equal<true, 10, Add<9, 1>>()
|
|
44
|
-
isType.equal<true, 11, Add<9, 2>>()
|
|
45
|
-
isType.equal<true, 12, Add<9, 3>>()
|
|
46
|
-
isType.equal<true, 13, Add<9, 4>>()
|
|
47
|
-
isType.equal<true, 14, Add<9, 5>>()
|
|
48
|
-
isType.equal<true, 15, Add<9, 6>>()
|
|
49
|
-
isType.equal<true, 16, Add<9, 7>>()
|
|
50
|
-
isType.equal<true, 17, Add<9, 8>>()
|
|
51
|
-
isType.equal<true, 18, Add<9, 9>>()
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
test('1 + 2 digits', () => {
|
|
56
|
-
isType.equal<true, 16, Add<3, 13>>()
|
|
57
|
-
isType.equal<true, 108, Add<9, 99>>()
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('2 + 1 digits', () => {
|
|
61
|
-
isType.equal<true, 16, Add<13, 3>>()
|
|
62
|
-
isType.equal<true, 108, Add<99, 9>>()
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('2 + 2 digits', () => {
|
|
66
|
-
isType.equal<true, 20, Add<10, 10>>()
|
|
67
|
-
isType.equal<true, 38, Add<19, 19>>()
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
test('n + n digits', () => {
|
|
71
|
-
isType.equal<true, 7777, Add<1234, 6543>>()
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
describe('Increment<A>', () => {
|
|
76
|
-
test('add 1', () => {
|
|
77
|
-
isType.equal<true, 1, Increment<0>>()
|
|
78
|
-
})
|
|
79
|
-
test('work with large number', () => {
|
|
80
|
-
isType.equal<true, 7777, Increment<7776>>()
|
|
81
|
-
})
|
|
82
|
-
})
|
|
1
|
+
import { Add, Increment, isType } from '..'
|
|
2
|
+
|
|
3
|
+
describe('Add<A, B>', () => {
|
|
4
|
+
test('fractional A gets never', () => {
|
|
5
|
+
isType.equal<true, never, Add<1.1, 1>>()
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test('negative A gets never', () => {
|
|
9
|
+
isType.equal<true, never, Add<-1, 1>>()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('fractional B gets never', () => {
|
|
13
|
+
isType.equal<true, never, Add<1, 1.2>>()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('negative B gets never', () => {
|
|
17
|
+
isType.equal<true, never, Add<1, -1>>()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('number gets Fail', () => {
|
|
21
|
+
isType.equal<true, never, Add<number, 1>>()
|
|
22
|
+
isType.equal<true, never, Add<1, number>>()
|
|
23
|
+
|
|
24
|
+
isType.equal<true, number, Add<number, 1, number>>()
|
|
25
|
+
isType.equal<true, number, Add<1, number, number>>()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('single digit', () => {
|
|
29
|
+
test('0 + n = n', () => {
|
|
30
|
+
isType.equal<true, 0, Add<0, 0>>()
|
|
31
|
+
isType.equal<true, 1, Add<0, 1>>()
|
|
32
|
+
isType.equal<true, 2, Add<0, 2>>()
|
|
33
|
+
isType.equal<true, 3, Add<0, 3>>()
|
|
34
|
+
isType.equal<true, 4, Add<0, 4>>()
|
|
35
|
+
isType.equal<true, 5, Add<0, 5>>()
|
|
36
|
+
isType.equal<true, 6, Add<0, 6>>()
|
|
37
|
+
isType.equal<true, 7, Add<0, 7>>()
|
|
38
|
+
isType.equal<true, 8, Add<0, 8>>()
|
|
39
|
+
isType.equal<true, 9, Add<0, 9>>()
|
|
40
|
+
})
|
|
41
|
+
test('9 + n', () => {
|
|
42
|
+
isType.equal<true, 9, Add<9, 0>>()
|
|
43
|
+
isType.equal<true, 10, Add<9, 1>>()
|
|
44
|
+
isType.equal<true, 11, Add<9, 2>>()
|
|
45
|
+
isType.equal<true, 12, Add<9, 3>>()
|
|
46
|
+
isType.equal<true, 13, Add<9, 4>>()
|
|
47
|
+
isType.equal<true, 14, Add<9, 5>>()
|
|
48
|
+
isType.equal<true, 15, Add<9, 6>>()
|
|
49
|
+
isType.equal<true, 16, Add<9, 7>>()
|
|
50
|
+
isType.equal<true, 17, Add<9, 8>>()
|
|
51
|
+
isType.equal<true, 18, Add<9, 9>>()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('1 + 2 digits', () => {
|
|
56
|
+
isType.equal<true, 16, Add<3, 13>>()
|
|
57
|
+
isType.equal<true, 108, Add<9, 99>>()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('2 + 1 digits', () => {
|
|
61
|
+
isType.equal<true, 16, Add<13, 3>>()
|
|
62
|
+
isType.equal<true, 108, Add<99, 9>>()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('2 + 2 digits', () => {
|
|
66
|
+
isType.equal<true, 20, Add<10, 10>>()
|
|
67
|
+
isType.equal<true, 38, Add<19, 19>>()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('n + n digits', () => {
|
|
71
|
+
isType.equal<true, 7777, Add<1234, 6543>>()
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('Increment<A>', () => {
|
|
76
|
+
test('add 1', () => {
|
|
77
|
+
isType.equal<true, 1, Increment<0>>()
|
|
78
|
+
})
|
|
79
|
+
test('work with large number', () => {
|
|
80
|
+
isType.equal<true, 7777, Increment<7776>>()
|
|
81
|
+
})
|
|
82
|
+
})
|