Search code examples
react-nativereact-navigationreact-navigation-stack

How to write type definitions while using nested navigation in react-navigation v5


I've write type definitions like this document says, however here comes problem while I'm using nested navigation.

Here come the sample codes:

in my App.tsx

export type MainStackParamList = {
  Setting: undefined
}
export type TabParamList = {
  Home: undefined
  Personal: undefined
}
const MainStack = createNativeStackNavigator<MainStackParamList>()
const Tab = createBottomTabNavigator<TabParamList>()
const RootStack = createNativeStackNavigator()

const MainStackScreen = () => (
  <MainStack.Navigator screenOptions={{ headerShown: false }}>
    <MainStack.Screen name="Setting" component={Setting} />
  </MainStack.Navigator>
)

const TabScreen = () => (
  <Tab.Navigator screenOptions={{ headerShown: false }}>
    <Tab.Screen name="Home" component={Setting} />
    <Tab.Screen name="Personal" component={Setting} />
  </Tab.Navigator>
)

const RootStackScreen = () => (
  <RootStack.Navigator screenOptions={{ headerShown: false }}>
    <RootStack.Screen name="Tab" component={TabScreen} />
    <RootStack.Screen name="Main" component={MainScreen} />
  </RootStack.Navigator>
)

in Home.tsx

type HomeRouteProp = RouteProp<TabParamList, 'Home'>
type HomeNavigationProp = CompositeNavigationProp<
  BottomTabNavigationProp<TabParamList, 'Home'>,
  NativeStackNavigationProp<MainStackParamList>
>
type Props = {
  route: HomeRouteProp
  navigation: HomeNavigationProp
}

 // ...

 navigation.navigate('Main', { screen: 'Setting' })

and typescript says that cannot assign 'Main' to type 'Home' | 'Personal' | 'Setting'


Solution

  • You also need to add types for your root stack.

    type RootStackParamList = {
      Tab: undefined;
      Main: undefined;
    }
    

    Then for your navigation prop:

    // Navigation prop for your MainStack
    type MainNavigationProp = CompositeNavigationProp<
      NativeStackNavigationProp<MainStackParamList, 'Setting'>,
      NativeStackNavigationProp<RootStackParamList>
    >
    
    // Navigation prop for your Home
    type HomeNavigationProp = CompositeNavigationProp<
      BottomTabNavigationProp<TabParamList, 'Home'>,
      MainNavigationProp
    >
    

    Combining navigation props using CompositeNavigationProp depends on nesting. Here, your Home screen is nested inside MainStack, so its navigation prop needs to be combined with MainStack's navigation prop.


    Previous answer:

    In your Stack, you have Setting and in your tabs, you have Home and Personal. There's no definition for Main anywhere, so the error is correct.

    Looks like your Main is your MainStack, which I guess you're rendering inside tabs? Then you need to add Main: undefined in TabParamList