React, условные реквизиты TypeScript - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь создать компонент 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. Когда есть опора «значок», принудительно "aria-label" и запретить дочерние элементы
  2. Если отсутствует свойство «icon», принудительно использовать дочерние элементы и разрешить необязательный параметр «aria-label»

1 Ответ

0 голосов
/ 02 августа 2020

Один из способов - объединить два варианта:

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

К сожалению, похоже, что запретить атрибуты в интерфейсе нелегко без обходного пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...