utilium 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -64,4 +64,106 @@ type StrictUnionHelper<T, TAll> = T extends unknown ? T & Partial<Record<Exclude
64
64
  * @see https://stackoverflow.com/a/65805753/17637456
65
65
  */
66
66
  export type StrictUnion<T> = Expand<StrictUnionHelper<T, T>>;
67
+ /**
68
+ * Empty
69
+ */
70
+ export type Empty = [];
71
+ /**
72
+ * Removes the first element of T and shifts
73
+ */
74
+ export type Shift<T> = T extends unknown[] ? (((...x: T) => void) extends (h: any, ...t: infer I) => void ? I : []) : unknown;
75
+ /**
76
+ * Gets the first element of T
77
+ */
78
+ export type First<T> = T extends unknown[] ? (((...x: T) => void) extends (h: infer I, ...t: any) => void ? I : []) : never;
79
+ /**
80
+ * Inserts A into T at the start of T
81
+ */
82
+ export type Unshift<T, A> = T extends unknown[] ? (((h: A, ...t: T) => void) extends (...i: infer I) => void ? I : unknown) : never;
83
+ /**
84
+ * Removes the last element of T
85
+ */
86
+ export type Pop<T> = T extends unknown[] ? (((...x: T) => void) extends (...i: [...infer I, any]) => void ? I : unknown) : never;
87
+ /**
88
+ * Gets the last element of T
89
+ */
90
+ export type Last<T> = T extends unknown[] ? (((...x: T) => void) extends (...i: [...infer H, infer I]) => void ? I : unknown) : never;
91
+ /**
92
+ * Appends A to T
93
+ */
94
+ export type Push<T, A> = T extends unknown[] ? (((...a: [...T, A]) => void) extends (...i: infer I) => void ? I : unknown) : never;
95
+ /**
96
+ * Concats A and B
97
+ */
98
+ export type Concat<A, B> = {
99
+ 0: A;
100
+ 1: Concat<Unshift<A, 0>, Shift<B>>;
101
+ }[Empty extends B ? 0 : 1];
102
+ /**
103
+ * Extracts from A what is not B
104
+ *
105
+ * @remarks
106
+ * It does not remove duplicates (so Remove\<[0, 0, 0], [0, 0]\> yields [0]). This is intended and necessary behavior.
107
+ */
108
+ export type Remove<A, B> = {
109
+ 0: A;
110
+ 1: Remove<Shift<A>, Shift<B>>;
111
+ }[Empty extends B ? 0 : 1];
112
+ /**
113
+ * The length of T
114
+ */
115
+ export type Length<T> = T extends {
116
+ length: number;
117
+ } ? T['length'] : never;
118
+ type _FromLength<N extends number, R = Empty> = {
119
+ 0: R;
120
+ 1: _FromLength<N, Unshift<R, 0>>;
121
+ }[Length<R> extends N ? 0 : 1];
122
+ /**
123
+ * Creates a tuple of length N
124
+ */
125
+ export type FromLength<N extends number> = _FromLength<N>;
126
+ /**
127
+ * Increments N
128
+ */
129
+ export type Increment<N extends number> = Length<Unshift<_FromLength<N>, 0>>;
130
+ /**
131
+ * Decrements N
132
+ */
133
+ export type Decrement<N extends number> = Length<Shift<_FromLength<N>>>;
134
+ /**
135
+ * Gets the sum of A and B
136
+ */
137
+ export type Add<A extends number, B extends number> = Length<Concat<_FromLength<A>, _FromLength<B>>>;
138
+ /**
139
+ * Subtracts B from A
140
+ */
141
+ export type Subtract<A extends number, B extends number> = Length<Remove<_FromLength<A>, _FromLength<B>>>;
142
+ /**
143
+ * Gets the type of an array's members
144
+ */
145
+ export type Member<T, D = null> = D extends 0 ? T : T extends (infer U)[] ? Member<U, D extends number ? Decrement<D> : null> : T;
146
+ /**
147
+ * Flattens an array
148
+ */
149
+ export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[] ? Member<Exclude<U, A>, D>[] : A extends unknown[] ? {
150
+ [K in keyof A]: Member<A[K], D>;
151
+ } : A;
152
+ /**
153
+ * Whether T is a tuple
154
+ */
155
+ export type IsTuple<T> = T extends [] ? false : T extends [infer Head, ...infer Rest] ? true : false;
156
+ /**
157
+ * Flattens a tuple
158
+ */
159
+ export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest] ? (U extends unknown[] ? [...U, ...FlattenTuple<Rest>] : [U, ...FlattenTuple<Rest>]) : [];
160
+ /**
161
+ * Flattens an array or tuple
162
+ */
163
+ export type Flatten<A extends unknown[]> = IsTuple<A> extends true ? FlattenTuple<A> : FlattenArray<A>;
164
+ type _Tuple<T, N extends number, R extends unknown[] = Empty> = R['length'] extends N ? R : _Tuple<T, N, [T, ...R]>;
165
+ /**
166
+ * Creates a tuple of T with length N
167
+ */
168
+ export type Tuple<T, N extends number> = _Tuple<T, N>;
67
169
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "utilium",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Typescript utilies",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/types.ts CHANGED
@@ -74,3 +74,119 @@ type StrictUnionHelper<T, TAll> = T extends unknown ? T & Partial<Record<Exclude
74
74
  * @see https://stackoverflow.com/a/65805753/17637456
75
75
  */
76
76
  export type StrictUnion<T> = Expand<StrictUnionHelper<T, T>>;
77
+
78
+ // Tuple and array manipulation
79
+
80
+ /**
81
+ * Empty
82
+ */
83
+ export type Empty = [];
84
+
85
+ /**
86
+ * Removes the first element of T and shifts
87
+ */
88
+ export type Shift<T> = T extends unknown[] ? (((...x: T) => void) extends (h: any, ...t: infer I) => void ? I : []) : unknown;
89
+
90
+ /**
91
+ * Gets the first element of T
92
+ */
93
+ export type First<T> = T extends unknown[] ? (((...x: T) => void) extends (h: infer I, ...t: any) => void ? I : []) : never;
94
+
95
+ /**
96
+ * Inserts A into T at the start of T
97
+ */
98
+ export type Unshift<T, A> = T extends unknown[] ? (((h: A, ...t: T) => void) extends (...i: infer I) => void ? I : unknown) : never;
99
+
100
+ /**
101
+ * Removes the last element of T
102
+ */
103
+ export type Pop<T> = T extends unknown[] ? (((...x: T) => void) extends (...i: [...infer I, any]) => void ? I : unknown) : never;
104
+
105
+ /**
106
+ * Gets the last element of T
107
+ */
108
+ export type Last<T> = T extends unknown[] ? (((...x: T) => void) extends (...i: [...infer H, infer I]) => void ? I : unknown) : never;
109
+
110
+ /**
111
+ * Appends A to T
112
+ */
113
+ export type Push<T, A> = T extends unknown[] ? (((...a: [...T, A]) => void) extends (...i: infer I) => void ? I : unknown) : never;
114
+
115
+ /**
116
+ * Concats A and B
117
+ */
118
+ export type Concat<A, B> = { 0: A; 1: Concat<Unshift<A, 0>, Shift<B>> }[Empty extends B ? 0 : 1];
119
+
120
+ /**
121
+ * Extracts from A what is not B
122
+ *
123
+ * @remarks
124
+ * It does not remove duplicates (so Remove\<[0, 0, 0], [0, 0]\> yields [0]). This is intended and necessary behavior.
125
+ */
126
+ export type Remove<A, B> = { 0: A; 1: Remove<Shift<A>, Shift<B>> }[Empty extends B ? 0 : 1];
127
+
128
+ /**
129
+ * The length of T
130
+ */
131
+ export type Length<T> = T extends { length: number } ? T['length'] : never;
132
+
133
+ type _FromLength<N extends number, R = Empty> = { 0: R; 1: _FromLength<N, Unshift<R, 0>> }[Length<R> extends N ? 0 : 1];
134
+
135
+ /**
136
+ * Creates a tuple of length N
137
+ */
138
+ export type FromLength<N extends number> = _FromLength<N>;
139
+
140
+ // compile-time math
141
+
142
+ /**
143
+ * Increments N
144
+ */
145
+ export type Increment<N extends number> = Length<Unshift<_FromLength<N>, 0>>;
146
+
147
+ /**
148
+ * Decrements N
149
+ */
150
+ export type Decrement<N extends number> = Length<Shift<_FromLength<N>>>;
151
+
152
+ /**
153
+ * Gets the sum of A and B
154
+ */
155
+ export type Add<A extends number, B extends number> = Length<Concat<_FromLength<A>, _FromLength<B>>>;
156
+
157
+ /**
158
+ * Subtracts B from A
159
+ */
160
+ export type Subtract<A extends number, B extends number> = Length<Remove<_FromLength<A>, _FromLength<B>>>;
161
+
162
+ /**
163
+ * Gets the type of an array's members
164
+ */
165
+ export type Member<T, D = null> = D extends 0 ? T : T extends (infer U)[] ? Member<U, D extends number ? Decrement<D> : null> : T;
166
+
167
+ /**
168
+ * Flattens an array
169
+ */
170
+ export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[] ? Member<Exclude<U, A>, D>[] : A extends unknown[] ? { [K in keyof A]: Member<A[K], D> } : A;
171
+
172
+ /**
173
+ * Whether T is a tuple
174
+ */
175
+ export type IsTuple<T> = T extends [] ? false : T extends [infer Head, ...infer Rest] ? true : false;
176
+
177
+ /**
178
+ * Flattens a tuple
179
+ */
180
+ export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest] ? (U extends unknown[] ? [...U, ...FlattenTuple<Rest>] : [U, ...FlattenTuple<Rest>]) : [];
181
+
182
+ /**
183
+ * Flattens an array or tuple
184
+ */
185
+ export type Flatten<A extends unknown[]> = IsTuple<A> extends true ? FlattenTuple<A> : FlattenArray<A>;
186
+
187
+ type _Tuple<T, N extends number, R extends unknown[] = Empty> = R['length'] extends N ? R : _Tuple<T, N, [T, ...R]>;
188
+
189
+ /**
190
+ * Creates a tuple of T with length N
191
+ */
192
+ export type Tuple<T, N extends number> = _Tuple<T, N>;