React Navigation+TypeScript:正确定义嵌套递归屏幕参数类型
问题核心
使用React Navigation嵌套栈结构时,自定义的StrictNavigatorParams类型无法正确解析NavigatorScreenParams<MainStack>这类被包裹的导航器参数类型,导致直接传入RootStack['MainNavigator']时无法生成预期的嵌套屏幕参数联合类型。
解决方案
修改StrictNavigatorParams类型,增加对NavigatorScreenParams的直接处理逻辑,先提取其内部的泛型类型再进行递归解析:
import { NavigatorScreenParams } from '@react-navigation/native'; // Root stack type RootStack = { MainNavigator: NavigatorScreenParams<MainStack>; }; // Main stack type MainStack = { SplashNavigator: NavigatorScreenParams<SplashStack>; AsNavigator: NavigatorScreenParams<AsStack>; }; type SplashStack = { SplashScreen: undefined; }; type AsStack = { AsScreen: { id: string }; }; // 修正后的严格导航参数类型 type StrictNavigatorParams<T> = // 优先处理被NavigatorScreenParams包裹的类型 T extends NavigatorScreenParams<infer InnerStack> ? StrictNavigatorParams<InnerStack> : T extends object ? { [K in keyof T]: T[K] extends NavigatorScreenParams<infer C> ? { screen: K; params: StrictNavigatorParams<C> } : { screen: K; params: T[K] }; }[keyof T] : never; // 验证根栈参数(原有功能保持正常) const rootExample: StrictNavigatorParams<RootStack> = { screen: 'MainNavigator', params: { screen: 'SplashNavigator', params: { screen: 'SplashScreen', params: undefined, }, }, }; // 验证直接访问MainNavigator的参数类型(现在符合预期) const mainExample: StrictNavigatorParams<RootStack['MainNavigator']> = { screen: 'AsNavigator', params: { screen: 'AsScreen', params: { id: '12', }, }, };
原理说明
- 新增的顶层条件判断
T extends NavigatorScreenParams<infer InnerStack>会优先识别被NavigatorScreenParams包裹的类型,直接提取内部的栈类型(比如MainStack)进行后续处理。 - 原有的递归逻辑保持不变,继续处理栈内的每个屏幕项,无论是普通屏幕还是嵌套的导航器。
- 这样无论传入的是原始栈类型,还是被
NavigatorScreenParams包裹的栈类型,都能正确生成对应的嵌套屏幕参数联合类型。
内容的提问来源于stack exchange,提问作者Okay Beydanol
相关产品推荐
相关产品推荐

