SunskyXH
SunskyXH

Reputation: 78

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'

Upvotes: 4

Views: 8189

Answers (2)

Hayden
Hayden

Reputation: 101

To improve upon the comments in the accepted answer, RootStackParamList should be typed as

type RootStackParamList = {
  Tab: NavigatorScreenParams<TabParamList>;
  Main: NavigatorScreenParams<MainStackParamList>;
}

Upvotes: 3

satya164
satya164

Reputation: 10143

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

Upvotes: 6

Related Questions