首页 > 解决方案 > React 和 Typescript 功能组件可以是 3 个接口之一

问题描述

我正在尝试创建一个可以使用 3 个接口中的 1 个的组件,该组件能够根据传递给它的道具来确定哪个接口。

interface CommonProps {
  label: string;
  icon?: React.ComponentType;
  role?: string;
}

interface ButtonProps extends CommonProps {
  handleOnClick: () => void;
  selected?: boolean;
  largeVariant?: boolean;
}

interface LinkProps {
  to: string;
  openInNewTab?: boolean;
}

interface HrefProps {
  href: string;
  openInNewTab?: boolean;
}

const Button: React.FC<ButtonProps | LinkProps | HrefProps> = props => {
  const { label, handleOnClick, to, href, icon, openInNewTab } = props;
  if (to || href) {
    const Component = to ? Link : 'a';
    return (
      <StyledButton
        component={Component}
        target={openInNewTab ? '_blank' : undefined}
        onMouseDown={(e: any) => {
          href && pushMatomoExternalLink(e, href);
        }}
        {...props}
      >
        {icon && <StyledIcon icon={icon} />}
        {label}
      </StyledButton>
    );
  }
  return (
    <StyledButton onClick={handleOnClick} {...props}>
      {icon && <StyledIcon icon={icon} />}
      {label}
    </StyledButton>
  );
};

期望的行为,包括我希望看到的错误。

<Button label="View Report" handleOnClick={action('BUTTON CLICKED')} />

会推断接口是ButtonProps

<Button label="View Report" selected />

TypeScript 错误:类型 '{ label: string; 中缺少属性 'handleOnClick' selected: boolean;}' 但在“ButtonProps”类型中是必需的。

<Button label="View Report" openInNewTab />

会推断该接口是 LinkProps 或 HrefProps

类型 '{ label: string; 中缺少属性 'to' openInNewTab:布尔值;}' 但在“LinkProps”类型中是必需的。

'{ label: string; 类型中缺少属性 'href' openInNewTab:布尔值;}' 但在 'HrefProps' 类型中是必需的。

<Button label="View Report" href="/" openInNewTab />

会推断出接口是 HrefProps

标签: reactjstypescript

解决方案


我不明白你的问题是什么;如果我采用您的确切代码,除了错误实现(假设最小可重现示例Button不需要此实现),编译器会给出您想要查看的错误

declare const Button: React.FC<ButtonProps | LinkProps | HrefProps>;
<Button label="View Report" handleOnClick={console.log} />;
// okay

<Button label="View Report" selected />; 
// Property 'handleOnClick' is missing in type '{ label: string; selected: true; }' 
// but required in type 'ButtonProps'.(2322)

<Button label="View Report" openInNewTab />;
// Property 'href' is missing in type '{ label: string; openInNewTab: true; }' 
// but required in type 'HrefProps'.(2322)

<Button label="View Report" href="/" openInNewTab />;
// okay

如果这不是您所期望的,或者问题实际上与 的实现有关Button,那么请编辑您的问题以指定您的问题是什么,包括一个可重现的示例,该示例准确显示您所看到的以及它与您的期望有何不同查看。祝你好运!

Playground 代码链接


推荐阅读