diff --git a/native/apps/apps-directory.react.js b/native/apps/apps-directory.react.js
--- a/native/apps/apps-directory.react.js
+++ b/native/apps/apps-directory.react.js
@@ -5,6 +5,8 @@
 import { useSelector } from 'react-redux';
 
 import AppListing from './app-listing.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
 import { useStyles } from '../themes/colors.js';
 
 const APP_DIRECTORY_DATA = [
@@ -24,8 +26,12 @@
   },
 ];
 
+type Props = {
+  +navigation: TabNavigationProp<'Apps'>,
+  +route: NavigationRoute<'Apps'>,
+};
 // eslint-disable-next-line no-unused-vars
-function AppsDirectory(props: { ... }): React.Node {
+function AppsDirectory(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
   const enabledApps = useSelector(state => state.enabledApps);
 
diff --git a/native/profile/add-keyserver.react.js b/native/profile/add-keyserver.react.js
--- a/native/profile/add-keyserver.react.js
+++ b/native/profile/add-keyserver.react.js
@@ -9,13 +9,19 @@
 import type { KeyserverInfo } from 'lib/types/keyserver-types.js';
 import { defaultConnectionInfo } from 'lib/types/socket-types.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import TextInput from '../components/text-input.react.js';
 import HeaderRightTextButton from '../navigation/header-right-text-button.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { useStyles, useColors } from '../themes/colors.js';
 
+type Props = {
+  +navigation: ProfileNavigationProp<'AddKeyserver'>,
+  +route: NavigationRoute<'AddKeyserver'>,
+};
 // eslint-disable-next-line no-unused-vars
-function AddKeyserver(props: { ... }): React.Node {
+function AddKeyserver(props: Props): React.Node {
   const { goBack, setOptions } = useNavigation();
 
   const dispatch = useDispatch();
diff --git a/native/profile/appearance-preferences.react.js b/native/profile/appearance-preferences.react.js
--- a/native/profile/appearance-preferences.react.js
+++ b/native/profile/appearance-preferences.react.js
@@ -10,8 +10,10 @@
   GlobalThemePreference,
 } from 'lib/types/theme-types.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import Button from '../components/button.react.js';
 import SWMansionIcon from '../components/swmansion-icon.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { type Colors, useColors, useStyles } from '../themes/colors.js';
 import { osCanTheme } from '../themes/theme-utils.js';
@@ -41,11 +43,12 @@
 }
 
 type Props = {
+  +navigation: ProfileNavigationProp<'AppearancePreferences'>,
+  +route: NavigationRoute<'AppearancePreferences'>,
   +globalThemeInfo: GlobalThemeInfo,
   +updateThemePreference: (themePreference: GlobalThemePreference) => mixed,
   +styles: typeof unboundStyles,
   +colors: Colors,
-  ...
 };
 class AppearancePreferences extends React.PureComponent<Props> {
   render() {
@@ -132,8 +135,14 @@
   },
 };
 
-const ConnectedAppearancePreferences: React.ComponentType<{ ... }> =
-  React.memo<{ ... }>(function ConnectedAppearancePreferences(props: { ... }) {
+type BaseProps = {
+  +navigation: ProfileNavigationProp<'AppearancePreferences'>,
+  +route: NavigationRoute<'AppearancePreferences'>,
+};
+const ConnectedAppearancePreferences: React.ComponentType<BaseProps> =
+  React.memo<BaseProps>(function ConnectedAppearancePreferences(
+    props: BaseProps,
+  ) {
     const globalThemeInfo = useSelector(state => state.globalThemeInfo);
     const updateThemePreference = useUpdateThemePreference();
 
diff --git a/native/profile/backup-menu.react.js b/native/profile/backup-menu.react.js
--- a/native/profile/backup-menu.react.js
+++ b/native/profile/backup-menu.react.js
@@ -8,14 +8,20 @@
 import { getMessageForException } from 'lib/utils/errors.js';
 import { entries } from 'lib/utils/objects.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import { useClientBackup } from '../backup/use-client-backup.js';
 import Button from '../components/button.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { setLocalSettingsActionType } from '../redux/action-types.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { useColors, useStyles } from '../themes/colors.js';
 
+type Props = {
+  +navigation: ProfileNavigationProp<'BackupMenu'>,
+  +route: NavigationRoute<'BackupMenu'>,
+};
 // eslint-disable-next-line no-unused-vars
-function BackupMenu(props: { ... }): React.Node {
+function BackupMenu(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
   const dispatch = useDispatch();
   const colors = useColors();
diff --git a/native/profile/build-info.react.js b/native/profile/build-info.react.js
--- a/native/profile/build-info.react.js
+++ b/native/profile/build-info.react.js
@@ -6,13 +6,19 @@
 
 import { useIsCurrentUserStaff } from 'lib/shared/staff-utils.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { persistConfig, codeVersion } from '../redux/persist.js';
 import { StaffContext } from '../staff/staff-context.js';
 import { useStyles } from '../themes/colors.js';
 import { isStaffRelease, useStaffCanSee } from '../utils/staff-utils.js';
 
+type Props = {
+  +navigation: ProfileNavigationProp<'BuildInfo'>,
+  +route: NavigationRoute<'BuildInfo'>,
+};
 // eslint-disable-next-line no-unused-vars
-function BuildInfo(props: { ... }): React.Node {
+function BuildInfo(props: Props): React.Node {
   const isCurrentUserStaff = useIsCurrentUserStaff();
   const { staffUserHasBeenLoggedIn } = React.useContext(StaffContext);
   const styles = useStyles(unboundStyles);
diff --git a/native/profile/default-notifications-preferences.react.js b/native/profile/default-notifications-preferences.react.js
--- a/native/profile/default-notifications-preferences.react.js
+++ b/native/profile/default-notifications-preferences.react.js
@@ -56,7 +56,7 @@
 }
 
 type BaseProps = {
-  +navigation: ProfileNavigationProp<>,
+  +navigation: ProfileNavigationProp<'DefaultNotifications'>,
   +route: NavigationRoute<'DefaultNotifications'>,
 };
 
diff --git a/native/profile/delete-account.react.js b/native/profile/delete-account.react.js
--- a/native/profile/delete-account.react.js
+++ b/native/profile/delete-account.react.js
@@ -12,8 +12,10 @@
 import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
 import { useDispatchActionPromise } from 'lib/utils/action-utils.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import { deleteNativeCredentialsFor } from '../account/native-credentials.js';
 import Button from '../components/button.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { useStyles } from '../themes/colors.js';
 import Alert from '../utils/alert.js';
@@ -22,7 +24,11 @@
   deleteAccountActionTypes,
 );
 
-const DeleteAccount: React.ComponentType<{ ... }> = React.memo<{ ... }>(
+type Props = {
+  +navigation: ProfileNavigationProp<'DeleteAccount'>,
+  +route: NavigationRoute<'DeleteAccount'>,
+};
+const DeleteAccount: React.ComponentType<Props> = React.memo<Props>(
   function DeleteAccount() {
     const loadingStatus = useSelector(loadingStatusSelector);
     const preRequestUserState = useSelector(preRequestUserStateSelector);
diff --git a/native/profile/emoji-user-avatar-creation.react.js b/native/profile/emoji-user-avatar-creation.react.js
--- a/native/profile/emoji-user-avatar-creation.react.js
+++ b/native/profile/emoji-user-avatar-creation.react.js
@@ -6,13 +6,19 @@
 import { EditUserAvatarContext } from 'lib/components/edit-user-avatar-provider.react.js';
 import { savedEmojiAvatarSelectorForCurrentUser } from 'lib/selectors/user-selectors.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import { useNativeSetUserAvatar } from '../avatars/avatar-hooks.js';
 import EmojiAvatarCreation from '../avatars/emoji-avatar-creation.react.js';
 import { displayActionResultModal } from '../navigation/action-result-modal.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 
+type Props = {
+  +navigation: ProfileNavigationProp<'EmojiUserAvatarCreation'>,
+  +route: NavigationRoute<'EmojiUserAvatarCreation'>,
+};
 // eslint-disable-next-line no-unused-vars
-function EmojiUserAvatarCreation(props: { ... }): React.Node {
+function EmojiUserAvatarCreation(props: Props): React.Node {
   const editUserAvatarContext = React.useContext(EditUserAvatarContext);
   invariant(editUserAvatarContext, 'editUserAvatarContext should be set');
 
diff --git a/native/profile/keyserver-selection-list.react.js b/native/profile/keyserver-selection-list.react.js
--- a/native/profile/keyserver-selection-list.react.js
+++ b/native/profile/keyserver-selection-list.react.js
@@ -7,6 +7,8 @@
 import type { SelectedKeyserverInfo } from 'lib/types/keyserver-types.js';
 
 import KeyserverSelectionListItem from './keyserver-selection-list-item.react.js';
+import type { ProfileNavigationProp } from './profile.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { useStyles } from '../themes/colors.js';
 
@@ -18,8 +20,12 @@
   return <KeyserverSelectionListItem {...item} />;
 }
 
+type Props = {
+  +navigation: ProfileNavigationProp<'KeyserverSelectionList'>,
+  +route: NavigationRoute<'KeyserverSelectionList'>,
+};
 // eslint-disable-next-line no-unused-vars
-function KeyserverSelectionList(props: { ... }): React.Node {
+function KeyserverSelectionList(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
 
   const selectedKeyserverInfos: $ReadOnlyArray<SelectedKeyserverInfo> =
diff --git a/native/profile/linked-devices.react.js b/native/profile/linked-devices.react.js
--- a/native/profile/linked-devices.react.js
+++ b/native/profile/linked-devices.react.js
@@ -1,8 +1,16 @@
 // @flow
+
 import * as React from 'react';
 
+import type { ProfileNavigationProp } from './profile.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+
+type Props = {
+  +navigation: ProfileNavigationProp<'LinkedDevices'>,
+  +route: NavigationRoute<'LinkedDevices'>,
+};
 // eslint-disable-next-line no-unused-vars
-function LinkedDevices(props: { ... }): React.Node {
+function LinkedDevices(props: Props): React.Node {
   return null;
 }
 
diff --git a/native/profile/privacy-preferences.react.js b/native/profile/privacy-preferences.react.js
--- a/native/profile/privacy-preferences.react.js
+++ b/native/profile/privacy-preferences.react.js
@@ -4,11 +4,17 @@
 import { View, Text } from 'react-native';
 import { ScrollView } from 'react-native-gesture-handler';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import ToggleReport from './toggle-report.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useStyles } from '../themes/colors.js';
 
+type Props = {
+  +navigation: ProfileNavigationProp<'PrivacyPreferences'>,
+  +route: NavigationRoute<'PrivacyPreferences'>,
+};
 // eslint-disable-next-line no-unused-vars
-function PrivacyPreferences(props: { ... }): React.Node {
+function PrivacyPreferences(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
 
   return (
diff --git a/native/profile/relationship-list.react.js b/native/profile/relationship-list.react.js
--- a/native/profile/relationship-list.react.js
+++ b/native/profile/relationship-list.react.js
@@ -89,7 +89,7 @@
   userInfo.username;
 
 type Props = {
-  +navigation: ProfileNavigationProp<>,
+  +navigation: ProfileNavigationProp<'FriendList' | 'BlockList'>,
   +route: NavigationRoute<'FriendList' | 'BlockList'>,
 };
 function RelationshipList(props: Props): React.Node {
diff --git a/native/profile/secondary-device-qr-code-scanner.react.js b/native/profile/secondary-device-qr-code-scanner.react.js
--- a/native/profile/secondary-device-qr-code-scanner.react.js
+++ b/native/profile/secondary-device-qr-code-scanner.react.js
@@ -7,13 +7,19 @@
 
 import { parseDataFromDeepLink } from 'lib/facts/links.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useStyles } from '../themes/colors.js';
 import Alert from '../utils/alert.js';
 
 const barCodeTypes = [BarCodeScanner.Constants.BarCodeType.qr];
 
+type Props = {
+  +navigation: ProfileNavigationProp<'SecondaryDeviceQRCodeScanner'>,
+  +route: NavigationRoute<'SecondaryDeviceQRCodeScanner'>,
+};
 // eslint-disable-next-line no-unused-vars
-function SecondaryDeviceQRCodeScanner(props: { ... }): React.Node {
+function SecondaryDeviceQRCodeScanner(props: Props): React.Node {
   const [hasPermission, setHasPermission] = React.useState(null);
   const [scanned, setScanned] = React.useState(false);
 
diff --git a/native/profile/tunnelbroker-menu.react.js b/native/profile/tunnelbroker-menu.react.js
--- a/native/profile/tunnelbroker-menu.react.js
+++ b/native/profile/tunnelbroker-menu.react.js
@@ -8,12 +8,18 @@
 import { useTunnelbroker } from 'lib/tunnelbroker/tunnelbroker-context.js';
 import type { TunnelbrokerMessage } from 'lib/types/tunnelbroker/messages.js';
 
+import type { ProfileNavigationProp } from './profile.react.js';
 import Button from '../components/button.react.js';
 import TextInput from '../components/text-input.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
 import { useColors, useStyles } from '../themes/colors.js';
 
+type Props = {
+  +navigation: ProfileNavigationProp<'TunnelbrokerMenu'>,
+  +route: NavigationRoute<'TunnelbrokerMenu'>,
+};
 // eslint-disable-next-line no-unused-vars
-function TunnelbrokerMenu(props: { ... }): React.Node {
+function TunnelbrokerMenu(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
   const colors = useColors();