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.
Files changed (120) hide show
  1. package/README.md +3 -1
  2. package/cjs/ComposableTypes.d.ts +0 -6
  3. package/cjs/JSONTypes.js +0 -1
  4. package/cjs/JSONTypes.js.map +1 -1
  5. package/cjs/UnionKeys.d.ts +0 -4
  6. package/cjs/array/CommonPropKeys.d.ts +0 -7
  7. package/cjs/array/CreateTuple.d.ts +10 -8
  8. package/cjs/array/DropMatch.d.ts +5 -0
  9. package/cjs/array/DropMatch.js +3 -0
  10. package/cjs/array/DropMatch.js.map +1 -0
  11. package/cjs/array/Filter.d.ts +2 -1
  12. package/cjs/array/FindFirst.d.ts +0 -3
  13. package/cjs/array/IntersectOfProps.d.ts +0 -7
  14. package/cjs/array/Last.d.ts +0 -3
  15. package/cjs/array/Tail.d.ts +0 -3
  16. package/cjs/array/UnionOfProps.d.ts +0 -7
  17. package/cjs/array/UnionOfValues.d.ts +0 -7
  18. package/cjs/array/index.d.ts +2 -1
  19. package/cjs/array/index.js.map +1 -1
  20. package/cjs/assertion/assertType.d.ts +0 -4
  21. package/cjs/assertion/assertType.js +0 -8
  22. package/cjs/assertion/assertType.js.map +1 -1
  23. package/cjs/functional/ChainFn.d.ts +0 -3
  24. package/cjs/functional/compose.d.ts +0 -3
  25. package/cjs/functional/compose.js +0 -3
  26. package/cjs/functional/compose.js.map +1 -1
  27. package/cjs/index.js +0 -2
  28. package/cjs/index.js.map +1 -1
  29. package/cjs/math/Add.d.ts +0 -6
  30. package/cjs/math/Digit.d.ts +20 -23
  31. package/cjs/math/IsPositive.d.ts +0 -5
  32. package/cjs/math/IsWhole.d.ts +0 -5
  33. package/cjs/math/Subtract.d.ts +0 -3
  34. package/cjs/nodejs/isNodeError.d.ts +0 -5
  35. package/cjs/nodejs/isNodeError.js +0 -5
  36. package/cjs/nodejs/isNodeError.js.map +1 -1
  37. package/cjs/nominal-types/Brand.d.ts +0 -10
  38. package/cjs/nominal-types/Brand.js +0 -3
  39. package/cjs/nominal-types/Brand.js.map +1 -1
  40. package/cjs/nominal-types/Flavor.d.ts +0 -12
  41. package/cjs/nominal-types/Flavor.js +0 -3
  42. package/cjs/nominal-types/Flavor.js.map +1 -1
  43. package/cjs/object/ExcludePropType.d.ts +0 -3
  44. package/cjs/object/IsDisjoint.d.ts +0 -4
  45. package/cjs/object/KeyTypes.d.ts +0 -5
  46. package/cjs/object/KeyofOptional.d.ts +0 -3
  47. package/cjs/object/KnownKeys.js +0 -3
  48. package/cjs/object/KnownKeys.js.map +1 -1
  49. package/cjs/object/Partial.d.ts +0 -9
  50. package/cjs/object/RecursiveIntersect.d.ts +0 -11
  51. package/cjs/object/Required.js +0 -1
  52. package/cjs/object/Required.js.map +1 -1
  53. package/cjs/object/facade.d.ts +0 -3
  54. package/cjs/object/facade.js +0 -3
  55. package/cjs/object/facade.js.map +1 -1
  56. package/cjs/object/mapProperties.d.ts +0 -8
  57. package/cjs/object/mapProperties.js +0 -8
  58. package/cjs/object/mapProperties.js.map +1 -1
  59. package/cjs/object/omit.d.ts +0 -3
  60. package/cjs/object/pick.d.ts +0 -7
  61. package/cjs/object/record.d.ts +0 -3
  62. package/cjs/object/record.js +0 -3
  63. package/cjs/object/record.js.map +1 -1
  64. package/cjs/object/reduceKey.d.ts +0 -3
  65. package/cjs/object/reduceKey.js +0 -3
  66. package/cjs/object/reduceKey.js.map +1 -1
  67. package/cjs/object/split.d.ts +0 -4
  68. package/cjs/predicates/CanAssign.d.ts +0 -3
  69. package/cjs/predicates/Equal.d.ts +0 -6
  70. package/cjs/predicates/isType.js +0 -6
  71. package/cjs/predicates/isType.js.map +1 -1
  72. package/cjs/promise/PromiseValue.d.ts +0 -3
  73. package/cjs/promise/PromiseValueMerge.d.ts +0 -3
  74. package/cjs/promise/isPromise.js +0 -1
  75. package/cjs/promise/isPromise.js.map +1 -1
  76. package/cjs/utils/Widen.d.ts +0 -4
  77. package/esm/JSONTypes.js +0 -1
  78. package/esm/JSONTypes.js.map +1 -1
  79. package/esm/array/DropMatch.js +2 -0
  80. package/esm/array/DropMatch.js.map +1 -0
  81. package/esm/array/index.js.map +1 -1
  82. package/esm/assertion/assertType.js +0 -8
  83. package/esm/assertion/assertType.js.map +1 -1
  84. package/esm/functional/compose.js +0 -3
  85. package/esm/functional/compose.js.map +1 -1
  86. package/esm/index.js +0 -2
  87. package/esm/index.js.map +1 -1
  88. package/esm/nodejs/isNodeError.js +0 -5
  89. package/esm/nodejs/isNodeError.js.map +1 -1
  90. package/esm/nominal-types/Brand.js +0 -3
  91. package/esm/nominal-types/Brand.js.map +1 -1
  92. package/esm/nominal-types/Flavor.js +0 -3
  93. package/esm/nominal-types/Flavor.js.map +1 -1
  94. package/esm/object/KnownKeys.js +0 -3
  95. package/esm/object/KnownKeys.js.map +1 -1
  96. package/esm/object/Required.js +0 -1
  97. package/esm/object/Required.js.map +1 -1
  98. package/esm/object/facade.js +0 -3
  99. package/esm/object/facade.js.map +1 -1
  100. package/esm/object/mapProperties.js +0 -8
  101. package/esm/object/mapProperties.js.map +1 -1
  102. package/esm/object/record.js +0 -3
  103. package/esm/object/record.js.map +1 -1
  104. package/esm/object/reduceKey.js +0 -3
  105. package/esm/object/reduceKey.js.map +1 -1
  106. package/esm/predicates/isType.js +0 -6
  107. package/esm/predicates/isType.js.map +1 -1
  108. package/esm/promise/isPromise.js +0 -1
  109. package/esm/promise/isPromise.js.map +1 -1
  110. package/package.json +1 -1
  111. package/ts/array/CreateTuple.spec.ts +32 -21
  112. package/ts/array/CreateTuple.ts +30 -7
  113. package/ts/array/DropMatch.spec.ts +113 -0
  114. package/ts/array/DropMatch.ts +53 -0
  115. package/ts/array/Filter.spec.ts +107 -21
  116. package/ts/array/Filter.ts +26 -12
  117. package/ts/array/index.ts +2 -1
  118. package/ts/math/Add.spec.ts +82 -82
  119. package/ts/math/Digit.spec.ts +184 -185
  120. package/ts/math/Digit.ts +20 -20
@@ -1,12 +1,35 @@
1
- import type { 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
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
- IsPositive<L> extends true ? CreateTuple.Device<[], L, T> : never
8
-
9
- export namespace CreateTuple {
10
- export type Device<R extends any[], L extends number, T> =
11
- R['length'] extends L ? R : Device<[T, ...R], L, T>
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[]))
@@ -1,21 +1,107 @@
1
- import { assertType, Equal, Filter } from '..'
2
-
3
- test('array matching criteria gets itself', () => {
4
- type Actual = Filter<string[], string>
5
- assertType.isTrue(true as Equal<string[], Actual>)
6
- })
7
-
8
- test('array not matching criteria gets never[]', () => {
9
- type Actual = Filter<string[], number>
10
- assertType.isTrue(true as Equal<never[], Actual>)
11
- })
12
-
13
- test('tuple filters to those matching criteria', () => {
14
- type Actual = Filter<[1, 2, 3, 4], 2 | 4>
15
- assertType.isTrue(true as Equal<[2, 4], Actual>)
16
- })
17
-
18
- test('tuple not value match criteria gets never[]', () => {
19
- type Actual = Filter<[1, 2, 3, 4], 5>
20
- assertType.isTrue(true as Equal<never[], Actual>)
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
+ })
@@ -1,12 +1,26 @@
1
- export type Filter<A extends Array<any>, Criteria> =
2
- number extends A['length']
3
- ? (A[0] extends Criteria ? A : never[])
4
- : (A['length'] extends 0
5
- ? never
6
- : (A extends [infer Head, ...infer Tail]
7
- ? (Tail['length'] extends 0
8
- ? (Head extends Criteria ? [Head] : never[])
9
- : (Head extends Criteria
10
- ? [Head, ...Filter<Tail, Criteria>]
11
- : Filter<Tail, Criteria>))
12
- : never))
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 { 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,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
+ })