首页 > 解决方案 > React,TypeScript 条件道具

问题描述

我正在尝试使用两个接口之间的管道类型创建一个带有条件道具的 React 组件。我的设置是这样的:

interface BaseProps {
  "aria-label"?: string;
  className?: string;
  onClick?: () => void;
}

interface IconProps extends BaseProps {
  "aria-label": string;
  children: never;
  icon: React.ReactElement;
}

interface ButtonProps extends BaseProps {
  children: React.ReactElement;
}

type Props = ButtonProps | IconProps;

class Button extends React.Component<Props> {
  render(): React.ReactElement {
    const { children, icon, ...rest } = this.props;
    // ERROR: "Property 'icon' does not exist on type '(Readonly<ButtonProps> & Readonly<{ children?: ReactNode; }>) | (Readonly<IconProps> & Readonly<{ children?: ReactNode; }>)'."
  }
}

我似乎无法弄清楚如何实现以下目标:

  1. 当有“icon”道具时,强制“aria-label”并禁止孩子
  2. 当没有“icon”道具时,强制孩子并允许可选的“aria-label”

标签: reactjstypescript

解决方案


一种方法是在两个变体之间建立一个联合:

interface VariantWithIconProps {
  icon: React.ReactElement,
  "aria-label": string;
}

interface VariantNoIconProps {
  "aria-label"?: string;
  children: React.ReactNode,
}

type Props = VariantWithIconProps | VariantNoIconProps;

const iconProps: VariantWithIconProps = {
  icon: <svg/>,
  "aria-label": "a",
};
const props1: Props = iconProps;
const props2: VariantNoIconProps = iconProps; // typescript error

const noIconProps1: VariantNoIconProps = {
  children: <div/>
};
const props3: Props = noIconProps1;
const props4: VariantWithIconProps = noIconProps1;  // typescript error

const noIconProps2: VariantNoIconProps = {
  children: <div/>,
  'aria-label': "a"
};
const props5: Props = noIconProps2;
const props6: VariantWithIconProps = noIconProps2;  // typescript error

不幸的是,如果没有变通方法,似乎很难在界面中禁止属性。


推荐阅读