How to compose ParamList for nested navigators in v5?

Viewed 797

Say I have two navigators like this:

export type RootStackParamList = {
  Bootstrap: undefined;
  Login: undefined;
  MainApp: undefined;
};

export type MainTabsParamList = {
  Explore: undefined;
  Profile: undefined;
};

const MainTabs = createBottomTabNavigator<MainTabsParamList>();
const MainApp = () => (
  <MainTabs.Navigator >
    <MainTabs.Screen
      name="Explore"
      component={Explore}
    />
    <MainTabs.Screen
      name="Profile"
      component={Profile}
    />
  </MainTabs.Navigator>
);

const RootStack = createStackNavigator<RootStackParamList>();
const App = () => {
  return (
    <NavigationContainer>
      <RootStack.Navigator initialRouteName="Bootstrap" headerMode="none">
        <RootStack.Screen name="Bootstrap" component={Bootstrap} />
        <RootStack.Screen name="Login" component={Login} />
        <RootStack.Screen name="MainApp" component={MainApp} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
};

Now if I want to navigate to Profile screen from Bootstrap screen. I have to write: (navigation prop properly annotated)

navigation.navigate('MainApp', {screen: 'Profile'})

But typescript gives error here. Saying Type '{ screen: string; }' is not assignable to type 'undefined'. This is because typescript doesn't know MainApp has child screens. So I have to somehow compose the ParamLists so typescript knows about the child screens. How do I do that? Does react-navigation v5 support that?

2 Answers

Looks like there no solution out of the box, BUT have found this thread (issue). There we may found good solution.

type NestedNavigatorParams<ParamList> = {
  [K in keyof ParamList]: undefined extends ParamList[K]
    ? { screen: K; params?: ParamList[K] }
    : { screen: K; params: ParamList[K] }
}[keyof ParamList]

It is very easy to use:

export type MainTabsParamList = {
  Explore: undefined;
  Profile: undefined;
};

export type RootStackParamList = {
  Bootstrap: undefined;
  Login: undefined;
  MainApp: NestedNavigatorParams<MainTabsParamList>;
};
Related