You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为useNavigation返回值指定类型?解决onError参数类型问题

解决React Navigation错误处理函数的类型问题

问题根源

  1. useNavigation()未指定泛型时,返回的是最基础的NavigationProp类型,不包含栈导航特有的replace、navigate等方法的完整类型定义,导致类型检查报错或运行时方法缺失。
  2. onError函数使用ReturnType<typeof useNavigation<...>>作为参数类型,过于间接且容易引入类型歧义。

修正方案

直接明确导航类型,避免依赖间接类型推导:

1. 为useNavigation指定精确泛型

在useErrorHandling中,给useNavigation传入栈导航的类型定义,确保返回的导航对象包含正确的方法:

export function useErrorHandling() {
  // 明确指定导航类型为NativeStackNavigationProp<RootStackParamList>
  const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();

  return { onError: (error: unknown) => onError(navigation, error) }; // 类型错误消除
}

2. 简化onError的参数类型

直接使用NativeStackNavigationProp<RootStackParamList>作为nav的参数类型,替代间接的ReturnType:

export function onError(
  nav: NativeStackNavigationProp<RootStackParamList>,
  error: unknown
) {
  // 此时nav的类型包含所有栈导航方法,类型检查和运行时都能保证方法存在
  nav.navigate('Error', { error: error instanceof Error ? error.message : 'Unknown error' });
  // nav.replace现在也能正确被类型检查,且运行时不会为undefined
}

完整修正后的代码

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<NativeStackNavigationProp<RootStackParamList>>();

  return { onError: (error: unknown) => onError(navigation, error) };
}

export function onError(
  // 使用直接的导航类型定义
  nav: NativeStackNavigationProp<RootStackParamList>,
  error: unknown
) {
  nav.navigate('Error', { error: error instanceof Error ? error.message : 'Unknown error' });
  // nav.replace现在类型正确,运行时也存在
}

原理说明

  • React Navigation的useNavigation默认返回基础导航类型,只有指定对应栈/标签页的导航泛型,才能获得该导航器特有的方法类型。
  • 直接使用NativeStackNavigationProp<RootStackParamList>作为参数类型,让类型检查更直接可靠,避免ReturnType带来的类型间接性问题,同时保证运行时方法存在。

内容的提问来源于stack exchange,提问作者Norfeldt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:55:18