我尝试了解如何将 React Navigation 与 TypeScript 一起使用...我遵循了 他们的 TypeScript 官方手册,所以我声明了所有必需的类型:
export type MainStackParamList = {
HomeScreen: undefined
MapScreen: undefined
PostScreen: undefined
ChatScreen: undefined
ProfileScreen: undefined
}
export type RootStackParamList = {
MainScreen: NavigatorScreenParams<MainStackParamList>
SettingsScreen: undefined
SignInScreen: undefined
SignUpScreen: undefined
SplashScreen: undefined
}
export type RootScreenProps<T extends keyof RootStackParamList> =
NativeStackScreenProps<RootStackParamList, T>
export type MainScreenProps = CompositeScreenProps<
RootScreenProps<'MainScreen'>,
MaterialBottomTabScreenProps<MainStackParamList>
>
我的应用程序屏幕结构如下:
Stack.Navigator
MainScreen
:Tab.Navigator
ProfileScreen
SettingsScreen
App.tsx:
const Stack = createNativeStackNavigator<RootStackParamList>()
const App = ({injector}: Props) => {
return (
<PaperProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="SplashScreen">
<Stack.Screen name="MainScreen">
{props => <MainScreen injector={injector} {...props} />}
</Stack.Screen>
<Stack.Screen
name="SettingsScreen"
component={SettingsScreen}
/>
// Other screens
</NavigationContainer>
</PaperProvider>
)
}
MainScreen.tsx:
const Tab = createMaterialBottomTabNavigator()
const MainScreen = ({injector}: Props) => {
return (
<Tab.Navigator
initialRouteName="HomeScreen">
<Tab.Screen
name="ProfileScreen">
{props => <ProfileScreen injector={injector} {...props} />}
</Tab.Screen>
// Other screens
</Tab.Navigator>
)
}
ProfileScreen.tsx:
type Props = {
injector: ProfileScreenInjector
} & MainScreenProps
const ProfileScreen = ({injector, navigation}: Props) => {
return // Profile view
}
在
ProfileScreen
(MainScreen
的子级)中,我需要调用外部导航器(Stack.Navigator
),类似于navigation.navigation('SettingsScreen')
之类的东西。但是,我在 MainScreen.tsx
: 中收到错误
Type '{ route: RouteProp<ParamListBase, "ProfileScreen">; navigation: any; injector: MainScreenInjector; }' is not assignable to type 'MainScreenProps'.
Types of property 'route' are incompatible.
Type 'RouteProp<ParamListBase, "ProfileScreen">' is not assignable to type 'RouteProp<RootStackParamList, "MainScreen">'.
Type 'RouteProp<ParamListBase, "ProfileScreen">' is not assignable to type 'Readonly<{ key: string; name: "MainScreen"; path?: string | undefined; }>'.
Types of property 'name' are incompatible.
Type '"ProfileScreen"' is not assignable to type '"MainScreen"'.ts(2322)
我做错了什么?如何在嵌套导航器中声明屏幕类型,以便它们可以调用根导航器?
好吧,我已经意识到我的错误,我需要更改
MainScreenProps
类型的声明,如下所示:
export type MainScreenProps<T extends keyof MainStackParamList> =
CompositeScreenProps<
MaterialBottomTabScreenProps<MainStackParamList, T>,
RootScreenProps<keyof RootStackParamList>
>
然后在
ProfileScreen
props 中为泛型类型指定一个右键:
type Props = {
injector: ProfileScreenInjector
} & MainScreenProps<'ProfileScreen'>
最后为
Tab
中的 MainScreen
定义添加缺失的泛型类型:
const Tab = createMaterialBottomTabNavigator<MainStackParamList>()
<Stack.Screen name="SignInScreen" component={SignInScreen} />
组件使用另一个屏幕参数
// SignInScreen.tsx
type SignInScreenProps = NativeStackScreenProps<
NavigationRootParamList,
'SignUpScreen' // 👈🏻 this here should be SignInScreen
>;
因此,您会收到错误
Type '"SignInScreen"' is not assignable to type '"SignUpScreen"'.ts(2322)