javascript - Typescript 中动态 React 组件的条件类型

标签 javascript reactjs typescript

尝试创建动态 React 组件。根据所选组件有条件地传递正确的 propType 的正确方法是什么。到目前为止,这是我在这一行 <SelectComponent {...props.props} /> 上遇到的错误因为 Prop 与组件不匹配:

export interface SidebarProps {
    type: keyof typeof components,
    props: AddEditJobsProps | AddEditCustomersProps
}

const components = {
  job: AddEditJobs,
  customer: AddEditCustomers
};

export default function Sidebar(props: SidebarProps) {
  const { open, toggle } = useToggle();
  const SelectComponent = components[props.type];

  return (
    <RightSidebar open={open} toggleDrawer={toggle}>
      <SelectComponent {...props.props} />
    </RightSidebar>
  );
}

编辑:任意添加到props中可以修复错误,但 Typescript 将无法匹配所选的类型 在类型检查期间使用相应的 props,这就是我希望在这里完成的任务。

export interface SidebarProps {
    type: keyof typeof components,
    props: AddEditJobsProps | AddEditCustomersProps | any
}

最佳答案

如果您坚持以这种方式保持动态,那么您可能应该这样做。

正如我在评论中提到的,第一个问题是 TS 直到运行时才知道 props.type 的值是什么,因此它无法有效地推断出它应该在前面的值时间。为了解决这个问题,您需要类似普通旧条件的东西来显式呈现正确的组件:

export const Sidebar: React.FC<SidebarProps> = props => {
  const { open, toggle } = useToggle();

  let inner: React.ReactNode;
  if (props.type === "job") {
    inner = <AddEditJobs {...props.props} />;
  } else if (props.type === "customer") {
    inner = <AddEditCustomers {...props.props} />;
  }

  return (
    <RightSidebar open={open} toggleDrawer={toggle}>
      {inner}
    </RightSidebar>
  );
};

请注意,条件基本上断言该字段的值是什么,这有助于 TS 推断形状的其余部分将是什么,并改进代码时类型检查。

第二个问题是您的 SidebarProps 界面过于宽松。

你有这个:

export interface SidebarProps {
    type: keyof typeof components,
    props: AddEditJobsProps | AddEditCustomersProps
}

这基本上是告诉 Typescript“该对象应该有一个与 components 中的键之一匹配的 type 字段,以及一个 props 字段是 AddEditJobsPropsAddEditCustomersProps”。但它没有指定如果 type 等于 "job"props 字段必须匹配 AddEditJobsProps。为此,您需要更明确地说:

export type SidebarProps =
  | {
      type: "job";
      props: AddEditJobsProps;
    }
  | { type: "customer"; props: AddEditCustomersProps };

这使用联合类型来确保 SidebarProps 具有一个或其他完整且有效的形状。

通过这些更改,不仅 Sidebar 中的 TS 错误消失,而且当您在另一个组件中渲染它时,您将获得预期的正确 TS 检查。如果 type"job"props 属性不具有 AddEditJobsProps 的预期形状,您将得到一个错误。在这个沙箱中亲自尝试一下:

https://codesandbox.io/s/youthful-fog-8lq41

关于javascript - Typescript 中动态 React 组件的条件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60122615/

相关文章:

javascript - 如何在 React Native 中为特定元素渲染 FlatList 内的函数

javascript - 在 React 中返回并渲染一个 div

reactjs - 如何从reactjs的下拉列表中获取选定值的键?

javascript - Uncaught Error : [$injector:modulerr] (newby)

javascript - 使用 ReactJS 显示/隐藏多个按钮

typescript - 如何将对象的键限制为 Typescript 中数组的字符串?

angular - 测试平台:错误:无法解析 PriDateInput 的所有参数:(?)

javascript - 参数 '[controllerName]' 不是 NaNunction,在转换为 TypeScript 时未定义

javascript - 光标X未定义(..)

javascript - CKEditor 将 HTML 插入文本区域