Home > Enterprise >  How to specify the type for the return of useNavigation
How to specify the type for the return of useNavigation

Time:09-07

I'm having some diffuculties specifing the parameters for a function (onError) that receive the return of a useNavigation())

import { BottomTabScreenProps } from '@react-navigation/bottom-tabs'
import { CompositeScreenProps, NavigatorScreenParams, useNavigation } from '@react-navigation/native'
import { NativeStackNavigationProp, NativeStackScreenProps } from '@react-navigation/native-stack'
import { AxiosError } from 'axios'

declare global {
  namespace ReactNavigation {
    interface RootParamList extends RootStackParamList {}
  }
}

export type RootStackParamList = {
  SignIn: undefined
  ResetPassword: { email: string }
  Tabs: NavigatorScreenParams<TabsParamList> | undefined
  Modal: undefined
  Error: { error: AxiosError | string } | undefined
}

export type TabsParamList = {
  Overview: NavigatorScreenParams<OverviewParamList> | undefined
  Allocation: undefined
  Menu: NavigatorScreenParams<MenuParamList> | undefined
}

export type OverviewParamList = {
  OverviewRoot: undefined
  Deposit: undefined
}

export type MenuParamList = {
  MenuRoot: undefined

  UserProfile: undefined
  // other settings
}

export type RouteName = keyof RootStackParamList | keyof OverviewParamList | keyof TabsParamList | keyof MenuParamList

export const routeTypeGuard = (route: RouteName) => route as keyof RootStackParamList

export type RootStackScreenProps<Screen extends keyof RootStackParamList> = NativeStackScreenProps<
  RootStackParamList,
  Screen
>

export type RootTabScreenProps<Screen extends keyof TabsParamList> = CompositeScreenProps<
  BottomTabScreenProps<TabsParamList, Screen>,
  NativeStackScreenProps<RootStackParamList>
>


export function useErrorHandling() {
  const navigation = useNavigation()
  // navigation.replace() // this throws a type error - which seems right

  return { one rror: (error: unknown) => one rror(navigation, error) } // how to avoid this to throw an error ??
}

export function one rror(
  nav: ReturnType<typeof useNavigation<NativeStackNavigationProp<RootStackParamList>>>,
  error: unknown
) {
  // nav.replace // does not throw type error, but experienced it to make the app crash because nav.replace was undefined
  nav.navigate('Error', { error: error instanceof Error ? error.message : 'Unknow error' })
}

TS playground

CodePudding user response:

Although this might not be the complete answer, here's a workaround to avoid the error:

const navigation = useNavigation<NativeStackNavigationProp<any>>()

CodePudding user response:

I have not personally worked with @react-navigation, so I'm going by the types only, but it looks like useNavigation, when called without type parameters, defaults to ReactNavigation.RootParamList which doesn't match your RootStackParamList.

If you specify type parameters RootStackParamList and keyof RootStackParamList to useNavigation, it type checks correctly:

export function useErrorHandling() {
  const navigation =
    useNavigation<NativeStackNavigationProp<RootStackParamList, keyof RootStackParamList>>()

  return { one rror: (error: unknown) => one rror(navigation, error) }
}

Additionally, you could simplify the nav argument type for onError a little bit by using NativeStackNavigationProp<RootStackParamList, keyof RootStackParamList> instead of the ReturnType application:

export function one rror(
  nav: NativeStackNavigationProp<RootStackParamList, keyof RootStackParamList>,
  error: unknown
) {
  nav.navigate('Error', { error: error instanceof Error ? error.message : 'Unknow error' })
}

TypeScript playground

  • Related