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

TypeScript中自定义Hook使用React Native useNavigation的类型问题解决

解决React Navigation自定义Hook的TypeScript类型问题

问题场景

使用@react-navigation的useNavigation创建自定义Hook时,遇到TypeScript类型不兼容问题,代码示例如下:

type RootStackParamList = {
  Login: { page: string } | undefined;
  Foo: { mode: string };
  Bar: undefined;
};

const useAuthNavigation = () => {
  const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();

  const navigate = (
    page: keyof RootStackParamList,
    params?: RootStackParamList[keyof RootStackParamList],
  ) => {
    navigation.navigate(page, params);
  };

  return { navigate };
};
export default useAuthNavigation;

错误信息(翻译后)

参数类型 [keyof RootStackParamList, { page: string; } | { mode: string; } | undefined] 无法赋值给类型 [screen: "Login"] | [screen: "Login", params: { page: string; } | undefined] | [screen: "Foo", params: { mode: string; }] | [screen: "Bar"] | [screen: "Bar", params: undefined]。
类型 [keyof RootStackParamList, { page: string; } | { mode: string; } | undefined] 无法赋值给类型 [screen: "Login", params: { page: string; } | undefined] | [screen: "Foo", params: { mode: string; }] | [screen: "Bar", params: undefined]。
类型 [keyof RootStackParamList, { page: string; } | { mode: string; } | undefined] 无法赋值给类型 [screen: "Bar", params: undefined]。
源类型第0位与目标类型第0位不兼容。
类型 keyof RootStackParamList 无法赋值给类型 "Bar"。
类型 "Login" 无法赋值给类型 "Bar"。ts(2345)

解决思路

问题核心在于原代码中page和params是独立的联合类型,TypeScript无法关联路由页面与对应参数的匹配关系,比如无法保证传入"Bar"时,params一定是undefined。

需要通过泛型约束两者的对应关系,让TypeScript能根据传入的页面自动推断合法的参数类型。

修正后的代码

import { useNavigation, NativeStackNavigationProp } from '@react-navigation/native-stack';

type RootStackParamList = {
  Login: { page: string } | undefined;
  Foo: { mode: string };
  Bar: undefined;
};

const useAuthNavigation = () => {
  const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();

  // 用泛型Screen关联页面与参数的对应类型
  const navigate = <Screen extends keyof RootStackParamList>(
    page: Screen,
    params?: RootStackParamList[Screen]
  ) => {
    navigation.navigate(page, params);
  };

  return { navigate };
};
export default useAuthNavigation;

说明

  • 新增泛型Screen,限定为RootStackParamList的键集合
  • 将params的类型约束为RootStackParamList[Screen],确保参数与当前页面严格匹配
  • 调用时TypeScript会自动校验:比如navigate("Bar")不允许传入非undefined的参数,navigate("Foo")必须传入{ mode: string }类型的参数,完全符合路由参数定义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:43:39