javascript - TypeScript-typ för värdet av en nyckel i ett objekt
Jag försöker definiera egna typer för ett navigeringsbibliotek med TypeScript, och jag har inte riktigt förstått hur man skapar en navigate-funktion som tar skärmens namn som första argument och skärmens egenskaper som andra argument samtidigt som det fortfarande är typsäkert.
Jag försöker:
- Skriv säkert skärmnamnet (
keyof Stack) som ett första argument - Kapsla säkert in mina två navigeringsstackar (
navigate<LoginStack>('HomeScreen')bör aldrig fungera, endast skärmarna frånLoginStackbör vara möjliga) - Använd de korrekta argumenten för motsvarande skärmnamn (
keyof Stack) som det andra argumentet
Min nuvarande metod:
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', {});
Medan jag uppnådde punkterna 1. och 2., är den andra parametern (argumenten) inte säkert typad eftersom de innehåller alla värden från HomeStackScreens-stacken:
Medan jag bara vill ha BaseProps & { isHeadless?: boolean } i det här fallet (Se HomeStackScreens-definitionen)
Svar #1
Prova detta!
function navigate<Stack extends {}>(
screenName: keyof Stack,
props: Stack[typeof screenName]
) {
// Implementation
}
Exempel,
type SomeStack = {
someScreen: {
test: string
}
}
navigate<SomeStack>('someScreen', {
test: 5 // Fails - should be a string!
})
