I'm working on a React Native project using TypeScript and React Navigation. I have a nested navigator setup where I have a BottomTabNavigator which contains a BlocklistStackNavigator. I'm facing a TypeScript error when trying to assign a component to a screen in the BlocklistStackNavigator. The error message is as follows:
TS2322: Type
({ navigation, route }: Readonly<EditBlocklistScreenProps>) => Element
is not assignable to type
ScreenComponentType<ParamListBase, BlocklistsStackScreens.EDIT_BLOCKLIST> | undefined
Type
({ navigation, route }: Readonly<EditBlocklistScreenProps>) => Element
is not assignable to type FunctionComponent<{}>
Types of parameters __0 and props are incompatible.
Type {} is missing the following properties from type Readonly<EditBlocklistScreenProps>: navigation, route
types.d.ts(318, 5): The expected type comes from property component which is declared here on type
IntrinsicAttributes & RouteConfig<ParamListBase, BlocklistsStackScreens.EDIT_BLOCKLIST, StackNavigationState<ParamListBase>, StackNavigationOptions, StackNavigationEventMap>
Here is the code from my BlocklistStackNavigator:
import { createStackNavigator } from '@react-navigation/stack'
import { BlocklistScreen } from '../screens/Blocklists/BlocklistScreen/BlocklistScreen.tsx'
import { BlocklistsStackScreens } from './screen-lists/BlocklistsStackScreens'
import { EditPlatformBlocklistScreen } from '../screens/Blocklists/EditPlatformBlocklistScreen'
import { CreateBlocklistScreen } from '../screens/Blocklists/CreateBlocklistScreen/CreateBlocklistScreen.tsx'
import { EditBlocklistScreen } from '../screens/Blocklists/EditBlocklistScreen/EditBlocklistScreen.tsx'
const Stack = createStackNavigator()
export function BlocklistStackNavigator() {
return (
<Stack.Navigator initialRouteName={BlocklistsStackScreens.MAIN_BLOCKLIST}>
<Stack.Screen
name={BlocklistsStackScreens.MAIN_BLOCKLIST}
component={BlocklistScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name={BlocklistsStackScreens.EDIT_BLOCKLIST}
options={{ headerShown: true }}
component={EditBlocklistScreen}
/>
<Stack.Screen
name={BlocklistsStackScreens.EDIT_PLATFORM_BLOCKLIST}
options={{ headerShown: true }}
component={EditPlatformBlocklistScreen}
/>
<Stack.Screen
name={BlocklistsStackScreens.CREATE_BLOCK_LIST}
options={{ headerShown: true }}
component={CreateBlocklistScreen}
initialParams={{ mode: 'create' }}
/>
</Stack.Navigator>
)
}
My EditBlocklistScreen :
import * as React from 'react'
import { BlocklistForm } from '../shared/BlocklistForm.tsx'
import { RouteProp } from '@react-navigation/native'
import { ScreenList } from '../../../navigators/screen-lists/screenLists.ts'
import { BlocklistsStackScreens } from '../../../navigators/screen-lists/BlocklistsStackScreens.ts'
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
import { TabScreens } from '../../../navigators/screen-lists/TabScreens.ts'
export type EditBlocklistScreenProps = {
navigation: NativeStackNavigationProp<ScreenList, TabScreens.BLOCKLIST>
route?: RouteProp<ScreenList, BlocklistsStackScreens.EDIT_BLOCKLIST>
}
export function EditBlocklistScreen({
navigation,
route,
}: Readonly<EditBlocklistScreenProps>) {
return (
<BlocklistForm
mode="edit"
navigation={navigation}
blocklistId={route?.params.blocklistId}
/>
)
}
The CreateBlocklistScreen:
import * as React from 'react'
import { BlocklistForm } from '../shared/BlocklistForm.tsx'
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
import { ScreenList } from '../../../navigators/screen-lists/screenLists.ts'
import { TabScreens } from '../../../navigators/screen-lists/TabScreens.ts'
export function CreateBlocklistScreen({
navigation,
}: Readonly<{
navigation: NativeStackNavigationProp<ScreenList, TabScreens.BLOCKLIST>
}>) {
return <BlocklistForm mode="create" navigation={navigation} />
}
I've tried making the navigation and route props optional in EditBlocklistScreenProps, but it didn't solve the issue. I suspect the problem might be related to the fact that I'm using nested navigators, but I'm not sure how to resolve it.
You may need to provide the ScreenList
in the createStackNavigator
:
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator<ScreenList>();
I can't see your ScreenList but make sure to define the route parameters. e.g:
type ScreenList = {
EditBlocklistScreen: { userId: string }; // userId is route param
};
Checkout the documentation for more details.