【问题标题】:React, TypeScript conditional propsReact,TypeScript 条件道具
【发布时间】:2020-08-02 01:21:29
【问题描述】:

我正在尝试使用两个接口之间的管道类型创建一个带有条件道具的 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”

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

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

    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
    

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

    【讨论】:

    • 不幸的是,这似乎只适用于纯 TS,但不适用于 React。我最终不得不使用这个答案中的UnionKeysStrictUnionHelperStrictUnion 类型:stackoverflow.com/questions/52771362/…
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2021-08-04
    • 2021-10-21
    • 2021-06-29
    • 2020-01-25
    相关资源
    最近更新 更多