问题描述
我正在尝试使用TypeScript为导航库定义自定义类型,而我并没有全力以赴创建一个navigate
函数,该函数以Screen的名称作为第一个参数,而Screen的属性为第二个参数,同时仍保持类型安全。
我正在尝试:
- 安全键入屏幕名称(
keyof Stack
)作为第一个参数 - 安全地封装我的两个导航堆栈(
navigate<LoginStack>('HomeScreen')
永远不会起作用,只能显示LoginStack
中的屏幕) - 为相应的屏幕名称(
keyof Stack
)使用正确的参数作为第二个参数
我目前的做法:
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',{});
虽然我获得了 1。和 2。分,但第二个参数(自变量)包含所有值,因此无法安全输入来自HomeStackScreens
堆栈:
在这种情况下,我只想拥有BaseProps & { isHeadless?: boolean }
(请参见HomeStackScreens
定义)
解决方法
尝试一下!
function navigate<Stack extends {}>(
screenName: keyof Stack,props: Stack[typeof screenName]
) {
// Implementation
}
示例
type SomeStack = {
someScreen: {
test: string
}
}
navigate<SomeStack>('someScreen',{
test: 5 // Fails - should be a string!
})