typescript - ข้อผิดพลาดชนิดของ React Navigation 5 เมื่อสลับไปมาระหว่างสแตก
ฉันกำลังเจอข้อผิดพลาดของ TypeScript บ้างเมื่อใช้ react-navigation 5 ฉันมั่นใจว่านี่เป็นความผิดพลาดของฉันเกี่ยวกับวิธีการพิมพ์สิ่งต่าง ๆ/การจัดโครงสร้างแอป แต่ฉันไม่แน่ใจว่าคืออะไร
ฉันกำลังติดตามคู่มือเหล่านี้ในเอกสารเป็นจุดเริ่มต้น:
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 ไม่มีเส้นทาง settings กำหนดอยู่ในนั้น ฉันควรสร้าง union type ของพารามิเตอร์ของทุกหน้าของสแต็กแล้วใช้มันทุกที่เพื่อที่ฉันจะได้ไม่พบข้อผิดพลาดนี้ หรือมีวิธีที่ดีกว่าในการจัดโครงสร้างนี้ไหม?
ฉันกำลังคิดว่าฉันอาจจะสร้างชนิด union ของรายการพารามิเตอร์ทั้งหมดแบบนี้ แต่ฉันไม่แน่ใจว่านี่เป็นวิธีที่ถูกต้องหรือเปล่า? อะไรประมาณนี้:
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>;
}
คำแนะนำหรือความช่วยเหลือใด ๆ ที่สามารถชี้ทางให้ฉันไปในทิศทางที่ถูกต้องจะเป็นที่ชื่นชมอย่างมาก ขอบคุณ
คำตอบ #1
ใช่ การรวมรายการพารามิเตอร์สำหรับกรณีการใช้นี้ก็โอเค