Typing Hooks and the Store in React Native with TypeScript
Typing Hooks and the Store
~15 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
cartStore.ts from chapter 12 is already typed – now it's the turn of the Redux Toolkit favorites store from chapter 3, EXACTLY like "React for Professionals" chapter 42, plus a React Native-specific detail: Reanimated's useSharedValue.
favoritesSlice.js to favoritesSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface FavoritesState {
skus: string[];
}
const initialState: FavoritesState = { skus: [] };
const favoritesSlice = createSlice({
name: 'favorites',
initialState,
reducers: {
toggleFavorite(state, action: PayloadAction<string>) {
const sku = action.payload;
if (state.skus.includes(sku)) {
state.skus = state.skus.filter((s) => s !== sku);
} else {
state.skus.push(sku);
}
},
},
});
export const { toggleFavorite } = favoritesSlice.actions;
export default favoritesSlice.reducer;store/index.js to index.ts
import { configureStore } from '@reduxjs/toolkit';
import favoritesReducer from './favoritesSlice';
export const store = configureStore({
reducer: {
favorites: favoritesReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;Creating store/hooks.ts: typed useSelector/useDispatch
Identical pattern to "React for Professionals" chapter 42:
import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux';
import type { RootState, AppDispatch } from './index';
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;From now on, use useAppSelector/useAppDispatch instead of the "bare" hooks from react-redux – the selector parameter automatically gets the correct RootState type:
// In FavoritesScreen.tsx / ProductListScreen.tsx:
import { useAppSelector, useAppDispatch } from '../store/hooks';
const favoriteSkus = useAppSelector((state) => state.favorites.skus);
const dispatch = useAppDispatch();Reanimated hooks: typed automatically, with one exception
useSharedValue, useAnimatedStyle, and withSpring from chapters 9/13 are already FULLY typed, without us doing anything – useSharedValue(1) automatically infers SharedValue<number>, EXACTLY like useState(1) automatically infers number (see "React for Professionals" chapter 42). ONE spot still needs attention: runOnJS from the Gesture Handler chapter.
import { runOnJS } from 'react-native-reanimated';
function onRemove(sku: string): void {
// ...
}
// TypeScript checks that runOnJS(onRemove)'s arguments match onRemove's signature:
runOnJS(onRemove)(item.sku); // sku: string - matches (sku: string) => voidAchtung: runOnJS is GENERIC over the function signature of the function passed to it – if you accidentally pass a number instead of a string (runOnJS(onRemove)(42)), TypeScript reports the error IMMEDIATELY. This is especially valuable with runOnJS, since a runtime error INSIDE a worklet (on the UI thread) is often harder to debug than a regular JS-thread error.
Typing Gesture.Pan() events
import { Gesture } from 'react-native-gesture-handler';
import { GestureUpdateEvent, PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
const panGesture = Gesture.Pan().onUpdate(
(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
translateX.value = Math.min(0, event.translationX);
}
);In practice, TypeScript usually infers the event type inside .onUpdate(...) AUTOMATICALLY and correctly, without the explicit annotation – it's shown here for CLARITY, to make explicit which type actually sits behind it, for the case where you extract event into a separate, named function (there, the explicit annotation becomes MANDATORY).
Tipp: Rule of thumb for third-party libraries: before writing a type by hand, check whether the library already EXPORTS it (like GestureUpdateEvent, PanGestureHandlerEventPayload here) – modern RN libraries like Reanimated and Gesture Handler are themselves written in TypeScript and ship precise, author-maintained types that are more reliable than hand-written approximations.