Skip to content

Commit 553aeb5

Browse files
authored
Add first version of types for useSelector hook
1 parent 9249108 commit 553aeb5

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

src/hooks/useSelector.js renamed to src/hooks/useSelector.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,35 @@ import { useReduxContext as useDefaultReduxContext } from './useReduxContext'
33
import Subscription from '../utils/Subscription'
44
import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
55
import { 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

Comments
 (0)