首页 > 解决方案 > 引用类型本身,TypeScript

问题描述

我正在尝试根据输入的值(屏幕名称)将类型(屏幕参数类型)传递给字段。

这是导航道具。

export interface IEditProfileStackNavigatorProps<RouteName extends keyof EditProfileRoutes> {
  navigation: StackNavigationProp<EditProfileRoutes, RouteName>;
  route: RouteProp<EditProfileRoutes, RouteName>;
}

和路线

export type EditProfileRoutes = {
  Options: undefined;
  Name: undefined;
  Username: { token: string };
  Bio: undefined;
  Location: undefined;
  VerifyUser: {
    screenToNavigateTo: keyof Omit<EditProfileRoutes, 'VerifyUser'> | keyof ManageAccountRoutes;
    params: any;
  };
};

我希望 params 根据导航功能中插入的屏幕名称接收屏幕的参数类型。

navigation.navigate('VerifyUser', {
  screenToNavigateTo: 'Username',
  params: { some: 'value' } }
)}

因此,如果插入的屏幕screenToNavigateTousername参数类型{ token: string },其余的将是undefined.

我的方法是做类似的事情

export type EditProfileRoutes = {
  Options: undefined;
  Name: undefined;
  Username: { token: string };
  Bio: undefined;
  Location: undefined;
  VerifyUser: {
    screenToNavigateTo: keyof Omit<EditProfileRoutes, 'VerifyUser'> | keyof ManageAccountRoutes;
    params?:EditProfileRoutes['VerifyUser']['screenToNavigateTo'];
  };
};

但这似乎不起作用

标签: javascripttypescriptreact-nativetypesreact-navigation

解决方案


您希望 的两个字段VerifyUser相互匹配,所以我们想要的是所有有效配对的联合。

这种通用 映射类型接受一个对象Routes并将其映射到具有相同键的新对象,但值是具有属性screenToNavigateTo和的对象paramsscreenToNavigateTo是来自的关键Routesparams是价值。

type RouteParams<Routes> = {
  [K in keyof Routes]: {
    screenToNavigateTo: K,
    params: Routes[K];
  }
}

然后我们[keyof Routes]在最后添加(一个索引访问类型)来抛弃键,只得到所有元素的联合。

type RouteParams<Routes> = {
  [K in keyof Routes]: {
    screenToNavigateTo: K,
    params: Routes[K];
  }
}[keyof Routes]

我们从中得到的已解决联合RouteParams<EditProfileRoutes>如下所示:

{
    screenToNavigateTo: "Options";
    params: undefined;
} | {
    screenToNavigateTo: "Name";
    params: undefined;
} | {
    screenToNavigateTo: "Username";
    params: {
        token: string;
    };
} | { ...

使用这种类型,我们现在可以定义EditProfileRoutes为:

export type EditProfileRoutes = {
  Options: undefined;
  Name: undefined;
  Username: { token: string };
  Bio: undefined;
  Location: undefined;
  VerifyUser: RouteParams<Omit<EditProfileRoutes, 'VerifyUser'>> | RouteParams<ManageAccountRoutes>
};

推荐阅读