I try to understand how to use React Navigation with TypeScript... I followed their official manual for TypeScript, so I've declared all required types:
export type MainStackParamList = { HomeScreen: undefined MapScreen: undefined PostScreen: undefined ChatScreen: undefined ProfileScreen: undefined}export type RootStackParamList = { MainScreen: NavigatorScreenParams<MainStackParamList> SettingsScreen: undefined SignInScreen: undefined SignUpScreen: undefined SplashScreen: undefined}export type RootScreenProps<T extends keyof RootStackParamList> = NativeStackScreenProps<RootStackParamList, T>export type MainScreenProps = CompositeScreenProps< RootScreenProps<'MainScreen'>, MaterialBottomTabScreenProps<MainStackParamList>>
My app screen structure is below:
- App:
Stack.Navigator
MainScreen
:Tab.Navigator
ProfileScreen
- ...
SettingsScreen
- ...
App.tsx:
const Stack = createNativeStackNavigator<RootStackParamList>()const App = ({injector}: Props) => { return (<PaperProvider><NavigationContainer><Stack.Navigator initialRouteName="SplashScreen"><Stack.Screen name="MainScreen"> {props => <MainScreen injector={injector} {...props} />}</Stack.Screen><Stack.Screen name="SettingsScreen" component={SettingsScreen} /> // Other screens</NavigationContainer></PaperProvider> )}
MainScreen.tsx:
const Tab = createMaterialBottomTabNavigator()const MainScreen = ({injector}: Props) => { return (<Tab.Navigator initialRouteName="HomeScreen"><Tab.Screen name="ProfileScreen"> {props => <ProfileScreen injector={injector} {...props} />}</Tab.Screen> // Other screens</Tab.Navigator> )}
ProfileScreen.tsx:
type Props = { injector: ProfileScreenInjector} & MainScreenPropsconst ProfileScreen = ({injector, navigation}: Props) => { return // Profile view}
In the ProfileScreen
(a child of the MainScreen
) I need to call an outer navigator (Stack.Navigator
), a something like navigation.navigation('SettingsScreen')
. However, I get an error in the MainScreen.tsx
:
Type '{ route: RouteProp<ParamListBase, "ProfileScreen">; navigation: any; injector: MainScreenInjector; }' is not assignable to type 'MainScreenProps'. Types of property 'route' are incompatible. Type 'RouteProp<ParamListBase, "ProfileScreen">' is not assignable to type 'RouteProp<RootStackParamList, "MainScreen">'. Type 'RouteProp<ParamListBase, "ProfileScreen">' is not assignable to type 'Readonly<{ key: string; name: "MainScreen"; path?: string | undefined; }>'. Types of property 'name' are incompatible. Type '"ProfileScreen"' is not assignable to type '"MainScreen"'.ts(2322)
What am I doing wrongly? How to declare types for screens in a nested navigator to they could call the root one?