简体   繁体   English

打字稿:X 类型的参数不能分配给 Y 和 X 类型的参数。X 类型不能分配给 Y 类型

[英]Typescript: Argument of type X is not assignable to parameter of type Y & X. Type X is not assignable to type Y

For a button link component, I'm trying to choose between HTMLButtonAttributes or HTMLAnchorAttributes based on passed props.对于按钮链接组件,我试图根据传递的道具在 HTMLButtonAttributes 或 HTMLAnchorAttributes 之间进行选择。 My knowledge of TypeScript is quite limited.我对 TypeScript 的了解非常有限。

I have the following types and interfaces:我有以下类型和接口:

interface CommonButtonProps {
   // custom props
}

export interface ButtonProps extends CommonButtonProps,
    React.ButtonHTMLAttributes<HTMLButtonElement> {}

export interface ButtonLinkProps extends CommonButtonProps,
    React.AnchorHTMLAttributes<HTMLAnchorElement> {
  href: string;
}

export type ButtonOrButtonLinkProps = ButtonProps | ButtonLinkProps;

export const isButtonLink = (props: ButtonOrButtonLinkProps,): props is ButtonLinkProps => guard logic

And the following Button component with ButtonOrButtonLinkProps:以及以下带有 ButtonOrButtonLinkProps 的 Button 组件:

export const Button: React.FC<ButtonOrButtonLinkProps> = props => {
  const buttonLink = isButtonLink(props);

  const commonProps = {
  };

  const linkProps: ButtonLinkProps = {
    ...commonProps,
    onClick: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
      // Do stuff
      if (props.onClick) {
        props.onClick(event); // Error
      }
    },
  };


  const buttonProps: ButtonProps = {
    ...commonProps,
    type: 'button',
    onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
      // Do other stuff
      if (props.onClick) {
        props.onClick(event); // Error
      }
    },
  };

  return (
    <StyledBtn {...(buttonLink ? linkProps : buttonProps)}>
      {children}
    </StyledBtn>
  );
};

The following line throws an error:以下行引发错误:

  if (props.onClick) {
    props.onClick(event); // Error
  }

Argument of type 'MouseEvent<HTMLButtonElement, MouseEvent>' is not assignable to parameter of type 'MouseEvent<HTMLButtonElement, MouseEvent> & MouseEvent<HTMLAnchorElement, MouseEvent>'. “MouseEvent<HTMLButtonElement, MouseEvent>”类型的参数不可分配给“MouseEvent<HTMLButtonElement, MouseEvent> & MouseEvent<HTMLAnchorElement, MouseEvent>”类型的参数。 Type 'MouseEvent<HTMLButtonElement, MouseEvent>' is not assignable to type 'MouseEvent<HTMLAnchorElement, MouseEvent>'.类型 'MouseEvent<HTMLButtonElement, MouseEvent>' 不能分配给类型 'MouseEvent<HTMLAnchorElement, MouseEvent>'。 Type 'HTMLButtonElement' is missing the following properties from type 'HTMLAnchorElement': charset, coords, download, hreflang, and 19 more. “HTMLButtonElement”类型缺少“HTMLAnchorElement”类型中的以下属性:字符集、坐标、下载、hreflang 等 19 个。

It seems the current type of onClick is似乎当前的onClick类型是在此处输入图片说明

Why is the event type and intersection of MouseEvent of HTMLButtonElement & MouseEvent of HTMLAnchorElement ?为什么是的MouseEvent的HTMLButtonElement的事件类型和路口& HTMLAnchorElement的的MouseEvent? I kinda expected it to be an union - either one or the other ?我有点期待它是一个工会——一个还是另一个?

Any idea how to fix the issue ?知道如何解决这个问题吗?

Probably you shouldn't do it this way可能你不应该这样做

Your component's props is public API of isolated code block, so you don't want to expand it too far.您的组件的 props 是隔离代码块的公共 API,因此您不想将其扩展得太远。 The best solution would be not to include all of link/button props into Button props, but include only necessary ones最好的解决方案是不要将所有的链接/按钮道具都包含Button道具中,而只包含必要的道具

But if you have to但如果你必须

The problem is that typescript does not understand what onClick type is, because it can be different based on props you pass.问题是打字稿不理解onClick类型是什么,因为它可能会根据您传递的道具而有所不同。 By the time typescript comes to props.onClick(execution) there are still ambiguity in type of props.props.onClick(execution)出现在props.onClick(execution) ,props 的类型仍然存在歧义。

Solution解决方案

Use your typeguard to let typescript know what type of props is使用你的 typeguard 让 typescript 知道 props 是什么类型

export const Button: React.FC<...> = props => {
  // props is of type `ButtonProps | ButtonLinkProps` here
  // so `onClick` is ambiguous too

  if (isButtonLink(props)) {
    // Do button link stuff
    // props is of type `ButtonLinkProps` here
  } else {
    // Do button stuff
    // props is of type `ButtonProps` here
  }

  // props is again of type `ButtonProps | ButtonLinkProps` here
  
  return (...);
}

Playground link on typeguards 打字机上的游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “X”类型的参数不能分配给“Y”类型的参数 - Argument of type 'X' is not assignable to parameter of type 'Y' TYPESCRIPT :类型“typeof X”的参数不能分配给类型为“Y”的带有扩展的参数 - TYPESCRIPT : Argument of type 'typeof X' is not assignable to parameter of type 'Y' with extends NGRX 减速器问题:“X”类型的参数不能分配给“Y”类型的参数 - NGRX reducer problem : Argument of type "X" is not assignable to parameter of type "Y" React Typescript:'{ [x: number]: any; 类型的参数 }' 不可分配给类型的参数 - React Typescript: Argument of type '{ [x: number]: any; }' is not assignable to parameter of type “x”类型的参数不能分配给 Angular7 中“x”类型的参数 - Argument of type 'x' is not assignable to parameter of type 'x' in Angular7 x 类型的参数不能分配给 '{ x: any; 类型的参数。 }' - Argument of type x is not assignable to parameter of type '{ x: any; }' &#39;number&#39; 类型的参数不能分配给类型 &#39;{ [x: number] }&#39; 的参数 - Argument of type 'number' is not assignable to parameter of type '{ [x: number] }' 设置组件状态时出现 TypeScript 错误:“X”类型的参数不可分配给“() =&gt; void”类型的参数 - TypeScript error when setting a component's state: Argument of type 'X' is not assignable to parameter of type '() => void' Typescript 错误“类型参数不可分配给类型参数” - Typescript error 'argument of type is not assignable to parameter of type' Typescript:a 类型的参数不能分配给 b 类型的参数 - Typescript: argument of type a is not assignable to parameter of type b
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM