尝试创建动态 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
字段是 AddEditJobsProps
或 AddEditCustomersProps
”。但它没有指定如果 type
等于 "job"
则 props
字段必须匹配 AddEditJobsProps
。为此,您需要更明确地说:
export type SidebarProps =
| {
type: "job";
props: AddEditJobsProps;
}
| { type: "customer"; props: AddEditCustomersProps };
这使用联合类型来确保 SidebarProps
具有一个或其他完整且有效的形状。
通过这些更改,不仅 Sidebar
中的 TS 错误消失,而且当您在另一个组件中渲染它时,您将获得预期的正确 TS 检查。如果 type
是 "job"
但 props
属性不具有 AddEditJobsProps
的预期形状,您将得到一个错误。在这个沙箱中亲自尝试一下:
关于javascript - Typescript 中动态 React 组件的条件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60122615/