@@ -3,29 +3,35 @@ import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
33import Subscription from '../utils/Subscription'
44import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
55import { ReactReduxContext } from '../components/Context'
6+ import { AnyAction , Store } from 'redux'
7+ import { DefaultRootState } from '../types'
68
7- const refEquality = ( a , b ) => a === b
9+ type EqualityFn < T > = ( a : T | undefined , b : T | undefined ) => boolean ;
810
9- function useSelectorWithStoreAndSubscription (
10- selector ,
11- equalityFn ,
12- store ,
13- contextSub
14- ) {
11+ const refEquality : EqualityFn < any > = ( a , b ) => a === b
12+
13+ type TSelector < S , R > = ( state : S ) => R ;
14+
15+ function useSelectorWithStoreAndSubscription < TStoreState , TSelectedState > (
16+ selector : TSelector < TStoreState , TSelectedState > ,
17+ equalityFn : EqualityFn < TSelectedState > ,
18+ store : Store < TStoreState , AnyAction > ,
19+ contextSub : Subscription
20+ ) : TSelectedState {
1521 const [ , forceRender ] = useReducer ( ( s ) => s + 1 , 0 )
1622
1723 const subscription = useMemo ( ( ) => new Subscription ( store , contextSub ) , [
1824 store ,
1925 contextSub ,
2026 ] )
2127
22- const latestSubscriptionCallbackError = useRef ( )
23- const latestSelector = useRef ( )
24- const latestStoreState = useRef ( )
25- const latestSelectedState = useRef ( )
28+ const latestSubscriptionCallbackError = useRef < Error > ( )
29+ const latestSelector = useRef < TSelector < TStoreState , TSelectedState > > ( )
30+ const latestStoreState = useRef < TStoreState > ( )
31+ const latestSelectedState = useRef < TSelectedState > ( )
2632
2733 const storeState = store . getState ( )
28- let selectedState
34+ let selectedState : TSelectedState | undefined
2935
3036 try {
3137 if (
@@ -65,7 +71,7 @@ function useSelectorWithStoreAndSubscription(
6571 function checkForUpdates ( ) {
6672 try {
6773 const newStoreState = store . getState ( )
68- const newSelectedState = latestSelector . current ( newStoreState )
74+ const newSelectedState = latestSelector . current ! ( newStoreState )
6975
7076 if ( equalityFn ( newSelectedState , latestSelectedState . current ) ) {
7177 return
@@ -92,7 +98,7 @@ function useSelectorWithStoreAndSubscription(
9298 return ( ) => subscription . tryUnsubscribe ( )
9399 } , [ store , subscription ] )
94100
95- return selectedState
101+ return selectedState !
96102}
97103
98104/**
@@ -101,12 +107,13 @@ function useSelectorWithStoreAndSubscription(
101107 * @param {React.Context } [context=ReactReduxContext] Context passed to your `<Provider>`.
102108 * @returns {Function } A `useSelector` hook bound to the specified context.
103109 */
104- export function createSelectorHook ( context = ReactReduxContext ) {
110+ export function createSelectorHook ( context = ReactReduxContext ) : < TState = DefaultRootState , Selected = unknown > ( selector : ( state : TState ) => Selected , equalityFn ?: EqualityFn < Selected > ) => Selected {
105111 const useReduxContext =
106112 context === ReactReduxContext
107113 ? useDefaultReduxContext
108114 : ( ) => useContext ( context )
109- return function useSelector ( selector , equalityFn = refEquality ) {
115+
116+ return function useSelector < TState , Selected extends unknown > ( selector : ( state : TState ) => Selected , equalityFn : EqualityFn < Selected > = refEquality ) : Selected {
110117 if ( process . env . NODE_ENV !== 'production' ) {
111118 if ( ! selector ) {
112119 throw new Error ( `You must pass a selector to useSelector` )
@@ -120,7 +127,7 @@ export function createSelectorHook(context = ReactReduxContext) {
120127 )
121128 }
122129 }
123- const { store, subscription : contextSub } = useReduxContext ( )
130+ const { store, subscription : contextSub } = useReduxContext ( ) !
124131
125132 const selectedState = useSelectorWithStoreAndSubscription (
126133 selector ,
0 commit comments