1
+ import type { MergeParameters } from './versionedTypes'
2
+ export type { MergeParameters } from './versionedTypes'
3
+
1
4
/*
2
5
*
3
6
* Reselect Data Types
@@ -94,56 +97,6 @@ export type GetParamsFromSelectors<
94
97
RemainingItems extends readonly unknown [ ] = Tail < MergeParameters < S > >
95
98
> = RemainingItems
96
99
97
- /** Given a set of input selectors, extracts the intersected parameters to determine
98
- * what values can actually be passed to all of the input selectors at once
99
- * WARNING: "you are not expected to understand this" :)
100
- */
101
- export type MergeParameters <
102
- // The actual array of input selectors
103
- T extends readonly UnknownFunction [ ] ,
104
- // Given those selectors, we do several transformations on the types in sequence:
105
- // 1) Extract "the type of parameters" for each input selector, so that we now have
106
- // a tuple of all those parameters
107
- ParamsArrays extends readonly any [ ] [ ] = ExtractParams < T > ,
108
- // 2) Transpose the parameter tuples.
109
- // Originally, we have nested arrays with "all params from input", "from input 2", etc:
110
- // `[ [i1a, i1b, i1c], [i2a, i2b, i2c], [i3a, i3b, i3c] ],
111
- // In order to intersect the params at each index, we need to transpose them so that
112
- // we have "all the first args", "all the second args", and so on:
113
- // `[ [i1a, i2a, i3a], [i1b, i2b, i3b], [i1c, i2c, i3c] ]
114
- // Unfortunately, this step also turns the arrays into a union, and weirder, it is
115
- // a union of all possible combinations for all input functions, so there's duplicates.
116
- TransposedArrays = Transpose < ParamsArrays > ,
117
- // 3) Turn the union of arrays back into a nested tuple. Order does not matter here.
118
- TuplifiedArrays extends any [ ] = TuplifyUnion < TransposedArrays > ,
119
- // 4) Find the longest params array out of the ones we have.
120
- // Note that this is actually the _nested_ data we wanted out of the transpose step,
121
- // so it has all the right pieces we need.
122
- LongestParamsArray extends readonly any [ ] = LongestArray < TuplifiedArrays >
123
- > =
124
- // After all that preparation work, we can actually do parameter extraction.
125
- // These steps work somewhat inside out (jump ahead to the middle):
126
- // 11) Finally, after all that, run a shallow expansion on the values to make the user-visible
127
- // field details more readable when viewing the selector's type in a hover box.
128
- ExpandItems <
129
- // 10) Tuples can have field names attached, and it seems to work better to remove those
130
- RemoveNames < {
131
- // 5) We know the longest params array has N args. Loop over the indices of that array.
132
- // 6) For each index, do a check to ensure that we're _only_ checking numeric indices,
133
- // not any field names for array functions like `slice()`
134
- [ index in keyof LongestParamsArray ] : LongestParamsArray [ index ] extends LongestParamsArray [ number ]
135
- ? // 9) Any object types that were intersected may have had
136
- IgnoreInvalidIntersections <
137
- // 8) Then, intersect all of the parameters for this arg together.
138
- IntersectAll <
139
- // 7) Since this is a _nested_ array, extract the right sub-array for this index
140
- LongestParamsArray [ index ]
141
- >
142
- >
143
- : never
144
- } >
145
- >
146
-
147
100
/*
148
101
*
149
102
* Reselect Internal Utility Types
@@ -153,28 +106,11 @@ export type MergeParameters<
153
106
/** Any function with arguments */
154
107
export type UnknownFunction = ( ...args : any [ ] ) => any
155
108
156
- /** An object with no fields */
157
- type EmptyObject = {
158
- [ K in any ] : never
159
- }
160
-
161
- type IgnoreInvalidIntersections < T > = T extends EmptyObject ? never : T
162
-
163
- /** Extract the parameters from all functions as a tuple */
164
- export type ExtractParams < T extends readonly UnknownFunction [ ] > = {
165
- [ index in keyof T ] : T [ index ] extends T [ number ] ? Parameters < T [ index ] > : never
166
- }
167
-
168
109
/** Extract the return type from all functions as a tuple */
169
110
export type ExtractReturnType < T extends readonly UnknownFunction [ ] > = {
170
111
[ index in keyof T ] : T [ index ] extends T [ number ] ? ReturnType < T [ index ] > : never
171
112
}
172
113
173
- /** Recursively expand all fields in an object for easier reading */
174
- export type ExpandItems < T extends readonly unknown [ ] > = {
175
- [ index in keyof T ] : T [ index ] extends T [ number ] ? Expand < T [ index ] > : never
176
- }
177
-
178
114
/** First item in an array */
179
115
export type Head < T > = T extends [ any , ...any [ ] ] ? T [ 0 ] : never
180
116
/** All other items in an array */
@@ -191,58 +127,6 @@ export type List<A = any> = ReadonlyArray<A>
191
127
192
128
export type Has < U , U1 > = [ U1 ] extends [ U ] ? 1 : 0
193
129
194
- /** Select the longer of two arrays */
195
- export type Longest < L extends List , L1 extends List > = L extends unknown
196
- ? L1 extends unknown
197
- ? { 0 : L1 ; 1 : L } [ Has < keyof L , keyof L1 > ]
198
- : never
199
- : never
200
-
201
- /** Recurse over a nested array to locate the longest one.
202
- * Acts like a type-level `reduce()`
203
- */
204
- export type LongestArray < S extends readonly any [ ] [ ] > =
205
- // If this isn't a tuple, all indices are the same, we can't tell a difference
206
- IsTuple < S > extends '0'
207
- ? // so just return the type of the first item
208
- S [ 0 ]
209
- : // If there's two nested arrays remaining, compare them
210
- S extends [ any [ ] , any [ ] ]
211
- ? Longest < S [ 0 ] , S [ 1 ] >
212
- : // If there's more than two, extract their types, treat the remainder as a smaller array
213
- S extends [ any [ ] , any [ ] , ...infer Rest ]
214
- ? // then compare those two, recurse through the smaller array, and compare vs its result
215
- Longest <
216
- Longest < S [ 0 ] , S [ 1 ] > ,
217
- Rest extends any [ ] [ ] ? LongestArray < Rest > : [ ]
218
- >
219
- : // If there's one item left, return it
220
- S extends [ any [ ] ]
221
- ? S [ 0 ]
222
- : never
223
-
224
- /** Recursive type for intersecting together all items in a tuple, to determine
225
- * the final parameter type at a given argument index in the generated selector. */
226
- export type IntersectAll < T extends any [ ] > = IsTuple < T > extends '0'
227
- ? T [ 0 ]
228
- : _IntersectAll < T >
229
-
230
- type IfJustNullish < T , True , False > = [ T ] extends [ undefined | null ]
231
- ? True
232
- : False
233
-
234
- /** Intersect a pair of types together, for use in parameter type calculation.
235
- * This is made much more complex because we need to correctly handle cases
236
- * where a function has fewer parameters and the type is `undefined`, as well as
237
- * optional params or params that have `null` or `undefined` as part of a union.
238
- *
239
- * If the next type by itself is `null` or `undefined`, we exclude it and return
240
- * the other type. Otherwise, intersect them together.
241
- */
242
- type _IntersectAll < T , R = unknown > = T extends [ infer First , ...infer Rest ]
243
- ? _IntersectAll < Rest , IfJustNullish < First , R , R & First > >
244
- : R
245
-
246
130
/*
247
131
*
248
132
* External/Copied Utility Types
@@ -253,32 +137,22 @@ type _IntersectAll<T, R = unknown> = T extends [infer First, ...infer Rest]
253
137
* Source: https://github.com/sindresorhus/type-fest/blob/main/source/union-to-intersection.d.ts
254
138
* Reference: https://github.com/microsoft/TypeScript/issues/29594
255
139
*/
256
- export type UnionToIntersection < Union > = (
140
+ export type UnionToIntersection < Union > =
257
141
// `extends unknown` is always going to be the case and is used to convert the
258
142
// `Union` into a [distributive conditional
259
143
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
260
- Union extends unknown
261
- ? // The union type is used as the only argument to a function since the union
262
- // of function arguments is an intersection.
263
- ( distributedUnion : Union ) => void
264
- : // This won't happen.
265
- never
266
- // Infer the `Intersection` type since TypeScript represents the positional
267
- // arguments of unions of functions as an intersection of the union.
268
- ) extends ( mergedIntersection : infer Intersection ) => void
269
- ? Intersection
270
- : never
271
-
272
- /**
273
- * Removes field names from a tuple
274
- * Source: https://stackoverflow.com/a/63571175/62937
275
- */
276
- type RemoveNames < T extends readonly any [ ] > = [ any , ...T ] extends [
277
- any ,
278
- ...infer U
279
- ]
280
- ? U
281
- : never
144
+ (
145
+ Union extends unknown
146
+ ? // The union type is used as the only argument to a function since the union
147
+ // of function arguments is an intersection.
148
+ ( distributedUnion : Union ) => void
149
+ : // This won't happen.
150
+ never
151
+ ) extends // Infer the `Intersection` type since TypeScript represents the positional
152
+ // arguments of unions of functions as an intersection of the union.
153
+ ( mergedIntersection : infer Intersection ) => void
154
+ ? Intersection
155
+ : never
282
156
283
157
/**
284
158
* Assorted util types for type-level conditional logic
@@ -313,7 +187,7 @@ type LastOf<T> = UnionToIntersection<
313
187
: never
314
188
315
189
// TS4.1+
316
- type TuplifyUnion <
190
+ export type TuplifyUnion <
317
191
T ,
318
192
L = LastOf < T > ,
319
193
N = [ T ] extends [ never ] ? true : false
@@ -331,21 +205,6 @@ export type ObjValueTuple<
331
205
? ObjValueTuple < T , KT , [ ...R , T [ K & keyof T ] ] >
332
206
: R
333
207
334
- /**
335
- * Transposes nested arrays
336
- * Source: https://stackoverflow.com/a/66303933/62937
337
- */
338
- type Transpose < T > = T [ Extract <
339
- keyof T ,
340
- T extends readonly any [ ] ? number : unknown
341
- > ] extends infer V
342
- ? {
343
- [ K in keyof V ] : {
344
- [ L in keyof T ] : K extends keyof T [ L ] ? T [ L ] [ K ] : undefined
345
- }
346
- }
347
- : never
348
-
349
208
/** Utility type to infer the type of "all params of a function except the first", so we can determine what arguments a memoize function accepts */
350
209
export type DropFirst < T extends unknown [ ] > = T extends [ unknown , ...infer U ]
351
210
? U
0 commit comments