Expo/React Native导航传参遇TypeScript类型不兼容错误求助
我正在用Expo和React Native开发应用,尝试通过navigation向其他页面传递参数。代码能正常编译且参数能传递成功,但调用navigation.navigate()时遇到两种类型错误:
传参时的错误:
Argument of type '[never, { email: string; password: string; }]' is not assignable to parameter of type 'never'.
不传参时的错误:
Argument of type 'string' is not assignable to parameter of type '{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: "SignUp"; key?: string | undefined; params: undefined; merge?: boolean | undefined; } | { key: string; params?: { email: string; password: string; } | undefined; merge?: boolean | undefined; } | ... 10 more ... | { ...; }'.ts(2345)
添加as never断言可以消除错误,但不确定这种临时方案是否合理,现寻求正确解决方案。
相关代码
SignUp.tsx 导航调用代码
import { RootStackParamList } from "../../App"; import { NativeStackScreenProps } from "@react-navigation/native-stack"; type propsType = NativeStackScreenProps<RootStackParamList, 'SignUp'>; const SignUp = (props: propsType) => { const {navigation} = props; // ...其他业务代码 return( // ...其他渲染内容 <MainButton canGoBack style={tw`h-20 justify-center mt-3 mx-auto`} text={"Sign up"} targetPage={"Characteristics"} onPress={() => navigation.navigate("Characteristics")} navigationData={{ email: formInput.email, password: formInput.password }} /> ) }
App.tsx 路由参数与导航栈定义
export type RootStackParamList = { Login: undefined; SignUp: undefined; ProfileSetup: undefined; ProfileSetupDetails: undefined; IdealMatch: undefined; Characteristics: { email: string, password: string; }; Profile: undefined; }; const Stack = createNativeStackNavigator<RootStackParamList>(); export type Props = NativeStackScreenProps<RootStackParamList, 'Characteristics'>; const App: React.FC<RootStackParamList> = () => { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Login" component={Login} options={{ headerShown: false }}/> <Stack.Screen name="SignUp" component={SignUp} options={{ headerShown: false }}/> <Stack.Screen name="ProfileSetup" component={ProfileSetup} options={{ headerShown: false }}/> <Stack.Screen name="ProfileSetupDetails" component={ProfileSetupDetails} options={{ headerShown: false }}/> <Stack.Screen name="IdealMatch" component={IdealMatch} options={{ headerShown: false }}/> <Stack.Screen name="Characteristics" component={Characteristics} options={{ headerShown: false }}/> <Stack.Screen name="Profile" component={Profile} options={{ headerShown: false }}/> </Stack.Navigator> </NavigationContainer> ); }
当前临时解决方案
const route = ["Characteristics", { email: formInput.email, password: formInput.password}]; navigation.navigate(...(route as never));
正确解决方案
问题根源是导航类型推导错误+App组件类型标注错误,按以下步骤修复:
- 修正App组件的类型标注
原代码中React.FC<RootStackParamList>是错误用法,React.FC不需要传入路由参数类型,改成:
const App: React.FC = () => { // ...原代码内容 }
或直接省略类型,TypeScript会自动推导。
- 正确调用
navigation.navigate
因为Characteristics页面定义了必填参数,直接按类型要求传入即可,TS会自动识别参数类型,无需数组展开或类型断言:
onPress={() => navigation.navigate("Characteristics", { email: formInput.email, password: formInput.password }) }
- 确保类型依赖正确
确认SignUp.tsx中正确导入了RootStackParamList,且propsType的类型标注无误,这样navigation对象会自动获得正确的类型提示,不需要额外断言。
关于临时方案的说明
as never是强制跳过TypeScript类型检查的断言,虽然能消除错误,但丢失了类型安全——如果参数格式错误,TS不会给出提示,容易引发运行时问题,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Georgi Traykov

