I have an issue with Typescript and React Navigation for my React Native app.
I've got the following setup in my project, which gives me awesome help and autocompletion when using e.g. navigation.push().
Types
import { StackNavigationProp } from '@react-navigation/stack';
export type RootStackParamList = {
Home: undefined;
Content: undefined;
List: undefined;
};
export type StackNavigationProps = StackNavigationProp<RootStackParamList>;
Usage
const navigation = useNavigation<StackNavigationProps>();
However, I've created a navigation handler function that takes a parameter that gets fed to navigation.push. It works fine as long as the type of the parameter is of type any.
const navigationHandler = useCallback((targetScreen) => {
navigation.push(targetScreen);
}, [navigation]);
But I am not satisfied with the any type and would prefer that targetScreen could in fact just be one of the screens that were declared in my RootStackParamList type. I have tried in countless ways to satisfy the push method of the navigation object but I'm stuck.
The following attempt has been the most successful but is yet not working exactly as it should. It does give me autocompletion on available screens, but the push is still unhappy.
Type:
export type NavigationScreen<T extends RootStackParamList> = {
[K in keyof T]: K;
}[keyof T];
Usage:
const navigationHandler = useCallback(
<T extends RootStackParamList>(targetScreen: NavigationScreen<T>) => {
navigation.push(targetScreen);
},[navigation]);
Hovering the error I get prompted with the following:
(parameter) targetScreen: { [K in keyof T]: K; }[keyof T] Argument of type '[{ [K in keyof T]: K; }[keyof T]]' is not assignable to parameter of type '["Home" | "Content" | "List"] | ["Home" | "Content" | "List", undefined]'. Type '[{ [K in keyof T]: K; }[keyof T]]' is not assignable to type '["Home" | "Content" | "List"]'.
Type 'keyof T' is not assignable to type '"Home" | "Content" | "List"'.
Type 'string | number | symbol' is not assignable to type '"Home" | "Content" | "List"'.
Type 'string' is not assignable to type '"Home" | "Content" | "List"'.
Type 'keyof T' is not assignable to type '"List"'.
Type 'string | number | symbol' is not assignable to type '"List"'.
Type 'string' is not assignable to type '"List"'.
How to get this working?