@@ -41,40 +41,9 @@ export type RootStateSelectors<RootState = any> = {
41
41
}
42
42
43
43
/**
44
- * Allows you to create a pre-typed version of
45
- * {@linkcode createStructuredSelector createStructuredSelector}
46
- * tailored to the provided root state type.
47
- *
48
- * @example
49
- * ```ts
50
- * import type { TypedStructuredSelectorCreator } from 'reselect'
51
- * import { createStructuredSelector } from 'reselect'
52
- *
53
- * interface RootState {
54
- * todos: {
55
- * id: number
56
- * completed: boolean
57
- * title: string
58
- * description: string
59
- * }[]
60
- * alerts: { id: number; read: boolean }[]
61
- * }
62
- *
63
- * export const createStructuredAppSelector: TypedStructuredSelectorCreator<RootState> =
64
- * createStructuredSelector
65
- *
66
- * const structuredSelector = createStructuredAppSelector({
67
- * // The `state` argument is correctly typed as `RootState`
68
- * todos: state => state.todos,
69
- * alerts: state => state.alerts
70
- * })
71
- *
72
- * ```
73
- *
44
+ * @deprecated Please use {@linkcode StructuredSelectorCreator.withTypes createStructuredSelector.withTypes<RootState>()} instead. This type will be removed in the future.
74
45
* @template RootState - The type of the root state object.
75
46
*
76
- * @see {@link https://reselect.js.org/api/createStructuredSelector#typedstructuredselectorcreator-since-500 `TypedStructuredSelectorCreator` }
77
- *
78
47
* @since 5.0.0
79
48
* @public
80
49
*/
@@ -205,22 +174,27 @@ export type TypedStructuredSelectorCreator<RootState = any> =
205
174
/**
206
175
* Represents an object where each property is a selector function.
207
176
*
177
+ * @template StateType - The type of state that all the selectors operate on.
178
+ *
208
179
* @public
209
180
*/
210
- export interface SelectorsObject {
211
- [ key : string ] : Selector
212
- }
181
+ export type SelectorsObject < StateType = any > = Record <
182
+ string ,
183
+ Selector < StateType >
184
+ >
213
185
214
186
/**
215
187
* It provides a way to create structured selectors.
216
188
* The structured selector can take multiple input selectors
217
189
* and map their output to an object with specific keys.
218
190
*
191
+ * @template StateType - The type of state that the structured selectors created with this structured selector creator will operate on.
192
+ *
219
193
* @see {@link https://reselect.js.org/api/createStructuredSelector `createStructuredSelector` }
220
194
*
221
195
* @public
222
196
*/
223
- export type StructuredSelectorCreator =
197
+ export interface StructuredSelectorCreator < StateType = any > {
224
198
/**
225
199
* A convenience function that simplifies returning an object
226
200
* made up of selector results.
@@ -327,7 +301,7 @@ export type StructuredSelectorCreator =
327
301
* @see {@link https://reselect.js.org/api/createStructuredSelector `createStructuredSelector` }
328
302
*/
329
303
<
330
- InputSelectorsObject extends SelectorsObject ,
304
+ InputSelectorsObject extends SelectorsObject < StateType > ,
331
305
MemoizeFunction extends UnknownMemoizer = typeof weakMapMemoize ,
332
306
ArgsMemoizeFunction extends UnknownMemoizer = typeof weakMapMemoize
333
307
> (
@@ -336,18 +310,64 @@ export type StructuredSelectorCreator =
336
310
MemoizeFunction ,
337
311
ArgsMemoizeFunction
338
312
>
339
- ) => OutputSelector <
313
+ ) : OutputSelector <
340
314
ObjectValuesToTuple < InputSelectorsObject > ,
341
315
Simplify < SelectorResultsMap < InputSelectorsObject > > ,
342
316
MemoizeFunction ,
343
317
ArgsMemoizeFunction
344
318
> &
345
319
InterruptRecursion
346
320
321
+ /**
322
+ * Creates a "pre-typed" version of
323
+ * {@linkcode createStructuredSelector createStructuredSelector}
324
+ * where the `state` type is predefined.
325
+ *
326
+ * This allows you to set the `state` type once, eliminating the need to
327
+ * specify it with every
328
+ * {@linkcode createStructuredSelector createStructuredSelector} call.
329
+ *
330
+ * @returns A pre-typed `createStructuredSelector` with the state type already defined.
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * import { createStructuredSelector } from 'reselect'
335
+ *
336
+ * export interface RootState {
337
+ * todos: { id: number; completed: boolean }[]
338
+ * alerts: { id: number; read: boolean }[]
339
+ * }
340
+ *
341
+ * export const createStructuredAppSelector =
342
+ * createStructuredSelector.withTypes<RootState>()
343
+ *
344
+ * const structuredAppSelector = createStructuredAppSelector({
345
+ * // Type of `state` is set to `RootState`, no need to manually set the type
346
+ * todos: state => state.todos,
347
+ * alerts: state => state.alerts,
348
+ * todoById: (state, id: number) => state.todos[id]
349
+ * })
350
+ *
351
+ * ```
352
+ * @template OverrideStateType - The specific type of state used by all structured selectors created with this structured selector creator.
353
+ *
354
+ * @see {@link https://reselect.js.org/api/createstructuredselector#defining-a-pre-typed-createstructuredselector `createSelector.withTypes` }
355
+ *
356
+ * @since 5.0.2
357
+ */
358
+ withTypes : <
359
+ OverrideStateType extends StateType
360
+ > ( ) => StructuredSelectorCreator < OverrideStateType >
361
+ }
362
+
347
363
/**
348
364
* A convenience function that simplifies returning an object
349
365
* made up of selector results.
350
366
*
367
+ * @param inputSelectorsObject - A key value pair consisting of input selectors.
368
+ * @param selectorCreator - A custom selector creator function. It defaults to `createSelector`.
369
+ * @returns A memoized structured selector.
370
+ *
351
371
* @example
352
372
* <caption>Modern Use Case</caption>
353
373
* ```ts
@@ -394,35 +414,41 @@ export type StructuredSelectorCreator =
394
414
*
395
415
* @public
396
416
*/
397
- export const createStructuredSelector : StructuredSelectorCreator = ( <
398
- InputSelectorsObject extends SelectorsObject ,
399
- MemoizeFunction extends UnknownMemoizer = typeof weakMapMemoize ,
400
- ArgsMemoizeFunction extends UnknownMemoizer = typeof weakMapMemoize
401
- > (
402
- inputSelectorsObject : InputSelectorsObject ,
403
- selectorCreator : CreateSelectorFunction <
404
- MemoizeFunction ,
405
- ArgsMemoizeFunction
406
- > = createSelector as CreateSelectorFunction <
407
- MemoizeFunction ,
408
- ArgsMemoizeFunction
409
- >
410
- ) => {
411
- assertIsObject (
412
- inputSelectorsObject ,
413
- 'createStructuredSelector expects first argument to be an object ' +
414
- `where each property is a selector, instead received a ${ typeof inputSelectorsObject } `
415
- )
416
- const inputSelectorKeys = Object . keys ( inputSelectorsObject )
417
- const dependencies = inputSelectorKeys . map ( key => inputSelectorsObject [ key ] )
418
- const structuredSelector = selectorCreator (
419
- dependencies ,
420
- ( ...inputSelectorResults : any [ ] ) => {
421
- return inputSelectorResults . reduce ( ( composition , value , index ) => {
422
- composition [ inputSelectorKeys [ index ] ] = value
423
- return composition
424
- } , { } )
425
- }
426
- )
427
- return structuredSelector
428
- } ) as StructuredSelectorCreator
417
+ export const createStructuredSelector : StructuredSelectorCreator =
418
+ Object . assign (
419
+ <
420
+ InputSelectorsObject extends SelectorsObject ,
421
+ MemoizeFunction extends UnknownMemoizer = typeof weakMapMemoize ,
422
+ ArgsMemoizeFunction extends UnknownMemoizer = typeof weakMapMemoize
423
+ > (
424
+ inputSelectorsObject : InputSelectorsObject ,
425
+ selectorCreator : CreateSelectorFunction <
426
+ MemoizeFunction ,
427
+ ArgsMemoizeFunction
428
+ > = createSelector as CreateSelectorFunction <
429
+ MemoizeFunction ,
430
+ ArgsMemoizeFunction
431
+ >
432
+ ) => {
433
+ assertIsObject (
434
+ inputSelectorsObject ,
435
+ 'createStructuredSelector expects first argument to be an object ' +
436
+ `where each property is a selector, instead received a ${ typeof inputSelectorsObject } `
437
+ )
438
+ const inputSelectorKeys = Object . keys ( inputSelectorsObject )
439
+ const dependencies = inputSelectorKeys . map (
440
+ key => inputSelectorsObject [ key ]
441
+ )
442
+ const structuredSelector = selectorCreator (
443
+ dependencies ,
444
+ ( ...inputSelectorResults : any [ ] ) => {
445
+ return inputSelectorResults . reduce ( ( composition , value , index ) => {
446
+ composition [ inputSelectorKeys [ index ] ] = value
447
+ return composition
448
+ } , { } )
449
+ }
450
+ )
451
+ return structuredSelector
452
+ } ,
453
+ { withTypes : ( ) => createStructuredSelector }
454
+ ) as StructuredSelectorCreator
0 commit comments