Thursday, May 9, 2024
 Popular · Latest · Hot · Upcoming
126
rated 0 times [  129] [ 3]  / answers: 1 / hits: 6710  / 4 Years ago, wed, august 19, 2020, 12:00:00

I'm trying to define custom typings for a navigation library using TypeScript, and I haven't wrapped my head around creating a navigate function that takes the Screen's name as a first argument, and the Screen's properties as a second argument while still being type safe.


I'm trying to:



  1. Safely type the screen name (keyof Stack) as a first argument

  2. Safely encapsulate my two navigation stacks (navigate<LoginStack>('HomeScreen') should never work, only the screens from LoginStack should be possible)

  3. Use the correct arguments for the corresponding screen name (keyof Stack) as the second argument


My current approach:


ScreenDefinitions.ts:


export interface LoginStackScreens {
LoginScreen: BaseProps & { isHeadless?: boolean };
ForgotPasswordScreen: BaseProps & { email: string };
}
export interface HomeStackScreens {
HomeScreen: BaseProps & { isHeadless?: boolean };
SavedScreen: BaseProps;
ChatsListScreen: BaseProps;
MyProfileScreen: BaseProps;
PostDetailsScreen: BaseProps & {
post: Post;
};
// ... some more
}

Navigation.ts:


type ValueOf<T> = T[keyof T];
function navigate<Stack extends HomeStackScreens | LoginStackScreens>(screenName: keyof Stack, props: ValueOf<Stack>): void {
// Navigation logic
}

navigate<HomeStackScreens>('HomeScreen', {});

While I achieved points 1. and 2., the second parameter (arguments) aren't safely typed as they contain all values from the HomeStackScreens stack:


Screenshot


Whereas I only want to have BaseProps & { isHeadless?: boolean } in this case (See HomeStackScreens definition)


More From » reactjs

 Answers
2

Try this!


function navigate<Stack extends {}>(
screenName: keyof Stack,
props: Stack[typeof screenName]
) {
// Implementation
}

Example,


type SomeStack = {
someScreen: {
test: string
}
}

navigate<SomeStack>('someScreen', {
test: 5 // Fails - should be a string!
})

[#2856] Saturday, August 15, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
harleyaleenag

Total Points: 678
Total Questions: 121
Total Answers: 105

Location: Papua New Guinea
Member since Thu, Jul 9, 2020
4 Years ago
harleyaleenag questions
Thu, May 5, 22, 00:00, 2 Years ago
Thu, Dec 26, 19, 00:00, 4 Years ago
;