typescript - 在堆栈之间导航时出现 React Navigation 5 类型错误
问题描述
我在使用 react-navigation 5 时遇到了一些 TypeScript 错误。我确定这是我在输入内容/构建应用程序方面做错的事情,但我不确定是什么。
我以文档中的这些指南为起点:
https://reactnavigation.org/docs/en/tab-based-navigation.html#a-stack-navigator-for-each-tab https://reactnavigation.org/docs/en/typescript.html
我想要一个这样的应用程序结构:
- 根标签导航器
- 家庭堆栈
- 主页
- 新闻详情页面
- 设置堆栈
- 设置页面
- 家庭堆栈
运行时一切正常,但是当我尝试从一个堆栈中的页面导航到另一个堆栈中的页面时,例如从新闻详细信息页面导航到设置页面时,我遇到了某种类型的错误。
这是我目前拥有的代码。
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { RouteProp } from '@react-navigation/core';
enum AppRoute {
// Home Stack
HOME = 'HOME',
NEWS_DETAILS = 'NEWS_DETAILS',
// Settings Stack
SETTINGS = 'SETTINGS',
}
type HomeStackParamList = {
[AppRoute.HOME]: undefined;
[AppRoute.NEWS_DETAILS]: {
id: number;
};
}
type SettingsStackParamList = {
[AppRoute.SETTINGS]: undefined;
}
type HomeProps = {
navigation: StackNavigationProp<
HomeStackParamList,
AppRoute.HOME
>;
route: RouteProp<HomeStackParamList, AppRoute.HOME>;
}
type NewsDetailsProps = {
navigation: StackNavigationProp<
HomeStackParamList,
AppRoute.NEWS_DETAILS
>;
route: RouteProp<HomeStackParamList, AppRoute.NEWS_DETAILS>;
}
type SettingsProps = {
navigation: StackNavigationProp<
SettingsStackParamList,
AppRoute.SETTINGS
>;
route: RouteProp<SettingsStackParamList, AppRoute.SETTINGS>;
}
// ----------------------------------------------------------------------------
function HomeScreen(props: HomeProps) {
const { navigation } = props;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate(AppRoute.NEWS_DETAILS, { id: 1 })}
/>
<Button
title="Go to Settings"
onPress={() => navigation.navigate(AppRoute.SETTINGS)}
/>
</View>
);
}
function DetailsScreen(props: NewsDetailsProps) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details! {props.route.params.id}</Text>
</View>
);
}
function SettingsScreen(props: SettingsProps) {
const { navigation } = props;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Home -> Details"
onPress={() => navigation.navigate(AppRoute.NEWS_DETAILS, { id: 2 })}
/>
</View>
);
}
const HomeStack = createStackNavigator<HomeStackParamList>();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name={AppRoute.HOME} component={HomeScreen} />
<HomeStack.Screen name={AppRoute.NEWS_DETAILS} component={DetailsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createStackNavigator<SettingsStackParamList>();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name={AppRoute.SETTINGS} component={SettingsScreen} />
</SettingsStack.Navigator>
);
}
const Tab = createBottomTabNavigator();
type TabNavigatorProps = React.ComponentProps<typeof Tab.Navigator>;
export const AppNavigator = (props: Partial<TabNavigatorProps>): React.ReactElement => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
);
}
这是我得到的错误:
No overload matches this call.
Argument of type '[AppRoute.SETTINGS]' is not assignable to parameter of type '[AppRoute.HOME | AppRoute.NEWS_DETAILS] | [AppRoute.HOME | AppRoute.NEWS_DETAILS, { id: number; }]'.
Type '[AppRoute.SETTINGS]' is not assignable to type '[AppRoute.HOME | AppRoute.NEWS_DETAILS]'.
Type 'AppRoute.SETTINGS' is not assignable to type 'AppRoute.HOME | AppRoute.NEWS_DETAILS'.
Overload 2 of 2, '(route: { key: string; params?: { id: number; }; } | { name: AppRoute.HOME | AppRoute.NEWS_DETAILS; key?: string; params: { id: number; }; }): void', gave the following error.
Argument of type 'AppRoute.SETTINGS' is not assignable to parameter of type '{ key: string; params?: { id: number; }; } | { name: AppRoute.HOME | AppRoute.NEWS_DETAILS; key?: string; params: { id: number; }; }'.ts(2769)
我想我明白为什么会发生这种情况,这是因为 HomeStackParamList 没有在其中定义设置路由。我应该为每个堆栈页面参数创建一个联合类型并在任何地方使用它,这样我就没有这个错误,还是有更好的方法来构建它?
我想我可以像这样创建所有参数列表的联合类型,但我不确定这是否是正确的方法?像这样的东西:
type HomeStackParamList = {
[AppRoute.HOME]: undefined;
[AppRoute.HOME_DETAILS]: {
id: number;
};
}
type SettingsStackParamList = {
[AppRoute.SETTINGS]: undefined;
}
type AppStackParamList = HomeStackParamList & SettingsStackParamList;
type HomeProps = {
navigation: StackNavigationProp<
AppStackParamList,
AppRoute.HOME
>;
route: RouteProp<AppStackParamList, AppRoute.HOME>;
}
type DetailsProps = {
navigation: StackNavigationProp<
AppStackParamList,
AppRoute.HOME_DETAILS
>;
route: RouteProp<AppStackParamList, AppRoute.HOME_DETAILS>;
}
type SettingsProps = {
navigation: StackNavigationProp<
AppStackParamList,
AppRoute.SETTINGS
>;
route: RouteProp<AppStackParamList, AppRoute.SETTINGS>;
}
任何帮助我指出正确方向的建议将不胜感激,谢谢
解决方案
是的,参数列表的联合对于这个用例来说很好。
推荐阅读
- javascript - 当我发送带有图像的发布请求时得到这个:错误:请求失败,状态码 409
- node.js - 如何让 cosmosdb 触发一个 azure 函数并调用另一个 http 函数
- sql - 得到 20 条 sql 查询的最佳 8 条结果?
- python - 'str' 对象在使用按类查找元素时不可调用 | 蟒蛇硒
- r - 在一行代码中创建多列,其中每一列是通过合并不同的列来创建的
- discord.py - 我的不和谐机器人在 Python 上的命令代码由于某种原因无法执行
- java - TypeError:“JavaPackage”对象在 google 协作中不可调用
- node.js - NODE_OPTIONS 中不允许 Docker 容器 --tls-min-v1.0
- mapbox - 从瓦片编号导出瓦片坐标
- sql - 在满足特定条件之前如何选择行