First, I show my type-definitions.
// Define screens. The key is a screen name. The value is a parameter passed to a navigation object. export type Screens = { } // Define your navigators. export type Navigators = { } type Navigatable<T> = T extends keyof Screens ? ScreenParams<T> : T extends keyof Navigators ? NavigatorParams<T> : never type ScreenParams<T extends keyof Screens> = { screen: T params: Screens[T] } type NavigatorParams<T extends keyof Navigators> = { screen: T params: Navigators[T] } export type NavigationParams = Screens & Navigators export type TypedNavigatorParams<T extends keyof Navigators> = Pick< NavigationParams, NavigationParams[T]['screen'] >
Usage
Read my repository for detail.
https://github.com/ryohlan/typesafe-react-navigation-sample
if you are considering the following structure:
AppNavigator - AuthNavigator - launch - signup - MainNavigator - MainTabNavigator - home - search
You can define the Screens and the Navigators the following:
// Define screens. The key is a screen name. The value is a parameter passed to a navigation object. export type Screens = { launch: {} signup: { signupParam: string } home: {} search: { searchParam: number } } // Define your navigators. export type Navigators = { AppNavigator: Navigatable<'AuthNavigator' | 'MainNavigator'> AuthNavigator: Navigatable<'launch'|'signup'> MainNavigator: Navigatable<'MainTabNavigator'> MainTabNavigator: Navigatable<'home'|'search> }
A Navigator also can be checked:
import React from 'react' import { createStackNavigator } from '@react-navigation/stack' import { TypedNavigatorParams } from './NavigationParams' import { LaunchScreen } from '../screens/LaunchScreen' const { Screen, Navigator } = createStackNavigator<TypedNavigatorParams<'AuthNavigator'>>() export const AuthNavigator = () => { return ( <Navigator mode="card"> <Screen {...LaunchScreen} /> </Navigator> ) }
And create custom hooks for navigation.
import { useNavigation as useDefaultNavigation } from '@react-navigation/core' import { StackNavigationProp } from '@react-navigation/stack' import { NavigationParams } from '@src/components/navigators/NavigationParams' export const useNavigation = () => useDefaultNavigation<StackNavigationProp<NavigationParams>>()
You can navigate type-safely using useNavigation!
const navigation = useNavigation() navigation.navigate('AppNavigator', { screen: 'AuthNavigator', params: { screen: 'signup', params: { signupParam: '' }, // If }, })
Top comments (0)