Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /** * Redux Selector Utilities * * Centralized selector utilities for memoization and type safety. * Uses createSelector from Redux Toolkit for efficient memoization. */ import { createSelector } from '@reduxjs/toolkit'; import type { RootState } from '../store'; // Re-export createSelector for consistent imports export { createSelector }; /** * Type helper for selector creation * Ensures proper typing for selector functions */ export type AppSelector<T> = (state: RootState) => T; /** * Type helper for parameterized selectors */ export type ParameterizedSelector<TParams, TResult> = ( state: RootState, params: TParams ) => TResult; /** * Create a typed selector with proper RootState inference * * @example * const selectUserName = createAppSelector(state => state.user.name); */ export function createAppSelector<T>(selector: AppSelector<T>): AppSelector<T> { return selector; } /** * Create a parameterized selector factory * Useful for selectors that need runtime parameters like IDs * * @example * const selectItemById = createParameterizedSelector( * (id: number) => createSelector( * [selectAllItems], * (items) => items.find(item => item.id === id) * ) * ); */ export function createParameterizedSelector<TParams, TResult>( selectorFactory: (params: TParams) => AppSelector<TResult> ): (params: TParams) => AppSelector<TResult> { const cache = new Map<string, AppSelector<TResult>>(); return (params: TParams) => { const key = JSON.stringify(params); if (!cache.has(key)) { cache.set(key, selectorFactory(params)); } return cache.get(key)!; }; } /** * Combine multiple selectors into one * Useful for components that need data from multiple slices * * @example * const selectCheckoutData = combineSelectors( * selectCartItems, * selectCurrentUser, * (cart, user) => ({ cart, user }) * ); */ export function combineSelectors<R1, R2, Result>( selector1: AppSelector<R1>, selector2: AppSelector<R2>, combiner: (r1: R1, r2: R2) => Result ): AppSelector<Result>; export function combineSelectors<R1, R2, R3, Result>( selector1: AppSelector<R1>, selector2: AppSelector<R2>, selector3: AppSelector<R3>, combiner: (r1: R1, r2: R2, r3: R3) => Result ): AppSelector<Result>; export function combineSelectors( ...args: [...AppSelector<unknown>[], (...results: unknown[]) => unknown] ): AppSelector<unknown> { const combiner = args.pop() as (...results: unknown[]) => unknown; const selectors = args as AppSelector<unknown>[]; return createSelector(selectors, combiner); } // Re-export all domain selectors export * from './cartSelectors'; export * from './wishlistSelectors'; |