TypeScript中如何让VerifyUser路由params匹配对应屏幕参数类型?
Let's fix this type issue so your VerifyUser route's params type correctly matches the target screen specified in screenToNavigateTo. The core problem with your original code is that you weren't mapping the screen name to its actual expected params type—instead, you were just reusing the screen name type directly for params, which doesn't work.
Step 1: Split Base Routes for Reusability
First, extract the non-VerifyUser routes into a separate type to make our type mappings cleaner:
// Define all edit profile routes EXCEPT VerifyUser type BaseEditProfileRoutes = { Options: undefined; Name: undefined; Username: { token: string }; Bio: undefined; Location: undefined; }; // Replace with your actual ManageAccountRoutes definition type ManageAccountRoutes = { AccountSettings: undefined; PasswordReset: { resetToken: string }; };
Step 2: Create a Conditional Params Mapper
Next, make a type that takes a screen name and returns the exact params type it expects:
// Define all possible target screens for VerifyUser type VerifyTargetScreen = keyof BaseEditProfileRoutes | keyof ManageAccountRoutes; // Map a target screen to its corresponding params type type VerifyScreenParams<T extends VerifyTargetScreen> = T extends keyof BaseEditProfileRoutes ? BaseEditProfileRoutes[T] : T extends keyof ManageAccountRoutes ? ManageAccountRoutes[T] : undefined;
Step 3: Build the Final EditProfileRoutes Type
Redefine EditProfileRoutes by merging our base routes with a union type for VerifyUser. This union type enforces that each screenToNavigateTo value is paired with its correct params type:
export type EditProfileRoutes = BaseEditProfileRoutes & { VerifyUser: { [Screen in VerifyTargetScreen]: { screenToNavigateTo: Screen; params: VerifyScreenParams<Screen>; }; }[VerifyTargetScreen]; };
How This Works
When you use navigation.navigate('VerifyUser', ...), TypeScript now enforces strict type matching:
- If
screenToNavigateTois'Username',paramsmust be{ token: string } - If
screenToNavigateTois any other screen fromBaseEditProfileRoutes(like'Name'or'Options'),paramsmust beundefined(or can be omitted entirely) - If
screenToNavigateTois a screen fromManageAccountRoutes, it uses that route's params type (e.g.,PasswordResetrequires{ resetToken: string })
Example Usage
// Valid: Username requires token param navigation.navigate('VerifyUser', { screenToNavigateTo: 'Username', params: { token: 'my-auth-token' } }); // Valid: Name doesn't require params (can omit or pass undefined) navigation.navigate('VerifyUser', { screenToNavigateTo: 'Name' }); // Invalid: TypeScript will throw an error (Username expects a token) navigation.navigate('VerifyUser', { screenToNavigateTo: 'Username', params: undefined });
Why Your Original Code Failed
Your original attempt set params?: EditProfileRoutes['VerifyUser']['screenToNavigateTo'], which just set params to the type of the screen name string (like 'Username' or 'Name'), not the actual params object the target screen expects. By using a mapped union type, we create a one-to-one link between each screen name and its required params.
内容的提问来源于stack exchange,提问作者Timothy Oliver

