So right now I have a routes.tsx file that holds all my types. But on the screens where I use useNavigation() I always need to create a type for it in that component. How do I properly set up a global type for my routes so I don’t have to do this?
routes.tsx
export type AuthStackParamList = {
Landing: undefined;
GetStarted: undefined;
VerifyOtp: { email: string };
PrivacyPolicy: undefined;
TermsOfService: undefined;
};
export type AppTabParamList = {
HomeScreen: undefined;
FriendsScreen: undefined;
NotificationsScreen: undefined;
SettingsScreen: undefined;
};
export type OnboardingStackParamList = {
UsernameScreen: undefined;
};
export type HomeTabStackParamList = {
Home: undefined;
};
export type FriendsTabStackParamList = {
Friends: undefined;
SearchUsers: undefined;
};
export type SettingsTabStackParamList = {
Settings: undefined;
EditName: { id: string; name: string };
EditUsername: { id: string; username: string };
DeleteAccount: undefined;
};
AuthStack.tsx
const AuthStack = createNativeStackNavigator<AuthStackParamList>();
export function AuthStackNavigator() {
return (
<AuthStack.Navigator
initialRouteName="Landing"
}}>
<AuthStack.Screen
name="Landing"
component={LandingScreen}
options={{ headerShown: false }}
/>
<AuthStack.Screen
name="GetStarted"
component={GetStartedScreen}
options={{ headerTitle: '' }}
/>
<AuthStack.Screen
name="VerifyOtp"
component={VerifyOTPScreen}
options={{ headerShown: false, gestureEnabled: false }}
/>
<AuthStack.Screen
name="TermsOfService"
component={TermsOfServiceScreen}
options={{ headerTitle: 'Terms of Service' }}
/>
<AuthStack.Screen
name="PrivacyPolicy"
component={PrivacyPolicy}
options={{ headerTitle: 'Privacy Policy' }}
/>
</AuthStack.Navigator>
);
}
GetStartedScreen.tsx
This is what I want to avoid having to do whenever I need to tap into useNavigation
type GetStartedScreenNavigationProps = NativeStackNavigationProp<
AuthStackParamList,
'GetStarted'
>;
const GetStartedScreen = () => {
const navigation = useNavigation<GetStartedScreenNavigationProps>();
3
Answers
I think there is no way to do that.
Because
useNavigation
is a hook.And a hook is always have to be created inside any component.
You can’t create the hook and export it to use in any other component.
According to the docs a declare global should work with useNavigation.
To do this, you can add this snippet somewhere in your codebase:
The RootParamList interface lets React Navigation know about the params accepted by your root navigator. Here we extend the type RootStackParamList because that’s the type of params for our stack navigator at the root. The name of this type isn’t important.
Here is a link to the chapter: https://reactnavigation.org/docs/typescript/#specifying-default-types-for-usenavigation-link-ref-etc
You could create a custom hook in a separate file like this:
And then in your screen: