Typing Navigation and API Data in React Native with TypeScript
Typing Navigation and API Data
~17 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
The most important React Native-specific TypeScript building block, with no equivalent in "React for Professionals": typing React Navigation. Without it, route.params in EVERY screen is simply any – TypeScript can't help with a typo like route.params.productSk (instead of productSku).
The central type: RootStackParamList
React Navigation expects ONE central type describing, for EVERY screen name, WHICH parameters it expects when navigated to (or undefined, if it needs none):
export type RootStackParamList = {
ProductList: undefined;
ProductDetail: { productSku: string };
Favorites: undefined;
Cart: undefined;
};ProductDetail: {{ productSku: string }} describes EXACTLY what we already know from "React Native for Beginners": navigation.navigate('ProductDetail', {{ productSku: item.sku }}). ProductList: undefined means: this screen expects NO parameters.
ProductDetailScreen.tsx: typing the props
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import type { RootStackParamList } from '../types/navigation';
type Props = NativeStackScreenProps<RootStackParamList, 'ProductDetail'>;
function ProductDetailScreen({ route }: Props) {
const { productSku } = route.params; // automatically recognized as string
// ...
}NativeStackScreenProps<RootStackParamList, 'ProductDetail'> – the SECOND type parameter ('ProductDetail') tells TypeScript WHICH entry from RootStackParamList applies. route.params is therefore automatically {{ productSku: string }}; route.params.productSk (a typo) would IMMEDIATELY show an error.
navigate() calls get checked too
// In ProductListScreen.tsx:
navigation.navigate('ProductDetail', { productSku: item.sku }); // ✓ correct
navigation.navigate('ProductDetail', { productSk: item.sku }); // ✗ TypeScript error
navigation.navigate('ProductDetail'); // ✗ TypeScript error: missing parameter
navigation.navigate('Favorites'); // ✓ correct, no parameter neededAchtung: This check only works if navigation itself is correctly typed – via the same NativeStackScreenProps<RootStackParamList, 'ProductList'> props in ProductListScreen.tsx. Forget this typing in ONE screen, and navigation.navigate(...) loses its type checking there, even though other screens stay correctly typed.
App.tsx: connecting the stack navigator to the type
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import type { RootStackParamList } from './types/navigation';
const Stack = createNativeStackNavigator<RootStackParamList>();createNativeStackNavigator<RootStackParamList>() connects ALL subsequent <Stack.Screen name="..."> entries to our central type – a name="ProductDetailx" (a typo in the screen name itself) would also be caught IMMEDIATELY as an error.
Typing magentoApi.ts
Just as in "React for Professionals" chapter 43: response.json() ALWAYS returns any, an API function's return type is an assertion, not an automatically checked guarantee.
export interface Product {
sku: string;
name: string;
price: number;
imageUrl: string;
}
interface MagentoApiItem {
sku: string;
name: string;
price: number;
image?: string;
}
function mapMagentoProduct(item: MagentoApiItem): Product {
return {
sku: item.sku,
name: item.name,
price: item.price,
imageUrl: item.image ?? 'https://picsum.photos/300',
};
}
export async function fetchProducts(): Promise<Product[]> {
const response = await fetch('https://api.example.com/products');
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json(); // type here: 'any'
return data.products.map(mapMagentoProduct);
}
export async function fetchProductBySku(sku: string): Promise<Product> {
const response = await fetch(`https://api.example.com/products/${sku}`);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
return mapMagentoProduct(data);
}export interface Product gets imported from now on everywhere a product gets processed – ProductCard's props could alternatively be modeled as {{ product: Product }} instead of individual name/price/imageUrl props, a sensible cleanup exercise for you.
Tipp: That completes the core project's TypeScript migration: the store (Zustand + Redux Toolkit), ProductCard, navigation, and the API layer are all typed. Finally, run npx tsc --noEmit from chapter 12 to check whether any type errors remain anywhere, before the next chapter continues with automated testing.