依赖于其他道具的动态道具

Dynamic props depending on other prop

我有这个组件,它只是一个标题和右边的一个图标,这个组件的容器可以是一个按钮,一个锚元素,或者一个来自[=12=的Link元素].

我能够像这样动态创建容器:

import { Link } from "react-router-dom";
// ....
type Props = {
  as: "button" | "a" | "Link";
  title: string;
  icon: string;
};
const ActionItem: React.FC<Props> = ({ as, title, icon }: Props) => {
  const Container = styled(as === "Link" ? Link : as)`
    display: flex;
    // ...
  `;

  return (
    <Container>
      {title}
      <div style={{ flex: 1 }} />
      {icon}
    </Container>
  );
};

但现在我想要完成的是根据 as 道具获得动态道具,例如,如果 as 道具等于 Link显示 Link 组件的所有道具,如 toreplace 等。或者如果 as 等于 a,则显示所有道具锚元素,如 hreftarget

<ActionItem 
  as="Link"
  to="/profile"
  ...
/>

我尝试了 this 但它没有用,主要是因为在示例中他们使用的是原生 HTML 元素,我需要使用这些(按钮和锚元素)加上 Link组件。

我不知道我正在寻找的东西是否可行,或者它是否是另一种可能的解决方案?

顺便说一句,here's a code sandbox 代码

编辑: 这是正常工作的代码 sandbox

您应该使用所谓的 discriminating union(或判别联合)。让我们使用 as 属性作为鉴别器。

您已经拥有

type Props = {
    as: "button" | "a" | "link"
}

将其分解为

type Props = 
    { as: "button" } | 
    { as: "a" } | 
    { as: "Link" }

现在只需向联合体的每个部分添加您期望 Typescript 推断出哪些其他可能属性的道具,给定鉴别器道具 as:

type Props = 
    { as: "button" } & ButtonProps | 
    { as: "a" } & AProps |
    { as: "Link" } & LinkProps

完成!

顺便说一下,我为你需要的补充道具使用了虚构的名称,你必须查找你想要与你自己的鉴别器道具相交的类型的名称。