I’ve got a tab navigator that has Home
and Profile
as screens. Home
is a stack navigator that contains RestaurantDetails
and RestaurantList
as screens.
I have a Button
that is in the RestaurantList
screen. I want to navigate to RestaurantDetails
.
Button.tsx
const Button = ({name}) => {
const navigation = useNavigation()
const onPress = () => {
navigation.navigate("RestaurantDetails", {name})
}
return (
<TouchableOpacity onPress={onPress}>
</TouchableOpacity>
)
}
The problem is that typescript complains
Argument of type '["RestaurantDetails", { name: string}]' is not assignable to parameter of type '[screen: "Home", params: NavigatorScreenParams<HomeStackParamList, Readonly<{ key: string; index: number; routeNames: string[]; history?: unknown[] | undefined; routes: NavigationRoute<ParamListBase, string>[]; type: string; stale: false; }>>] | [screen: ...] | [screen: ...] | [screen: ...] | [screen: ...]'.
Type '["RestaurantDetails", { name: string}]' is not assignable to type '[screen: "Profile", params: undefined]'.
Type at position 0 in source is not compatible with type at position 0 in target.
Type '"RestaurantDetails"' is not assignable to type '"Profile"'.
I’m pretty sure the problem is that typescript looks in TRootParamList
instead of HomeStackParamList
for the RestaurantDetails
screen, since if I add RestaurantDetails
to TRootParamList
typescript stops complaining. However, I am unsure on how to actually stop this problem.
types.ts
import { NavigatorScreenParams } from '@react-navigation/native';
type QueueDetailsParams = {
name: string
};
type HomeStackParamList = {
RestaurantDetails: QueueDetailsParams | undefined;
RestaurantList: undefined
};
type TRootParamList = {
Home: NavigatorScreenParams<HomeStackParamList>;
Profile: undefined
};
declare global {
namespace ReactNavigation {
interface RootParamList extends TRootParamList {}
}
}
P.S
I know that I can replace my onPress
with the below but would rather not do this.
const onPress = () => {
navigation.navigate("Home", {screen: "RestaurantDetails", params: {name}})
}
2
Answers
Let me know if importing navigation from props solves your problem, if not we can debug it further:
When you use the
useNavigation
hook, you have to type it with the StackNavigationProp and the param list that includes the target screen:Then you can use it with any screen in that param list: