javascript - 打字稿:X 类型的参数不可分配给 Y 和 X 类型的参数。X 类型不可分配给 Y
问题描述
对于按钮链接组件,我试图根据传递的道具在 HTMLButtonAttributes 或 HTMLAnchorAttributes 之间进行选择。我对 TypeScript 的了解非常有限。
我有以下类型和接口:
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
以及以下带有 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>
);
};
以下行引发错误:
if (props.onClick) {
props.onClick(event); // Error
}
“MouseEvent<HTMLButtonElement, MouseEvent>”类型的参数不能分配给“MouseEvent<HTMLButtonElement, MouseEvent> & MouseEvent<HTMLAnchorElement, MouseEvent>”类型的参数。类型“MouseEvent<HTMLButtonElement, MouseEvent>”不可分配给类型“MouseEvent<HTMLAnchorElement, MouseEvent>”。“HTMLButtonElement”类型缺少“HTMLAnchorElement”类型中的以下属性:字符集、坐标、下载、hreflang 等 19 个。
为什么 HTMLButtonElement 的 MouseEvent 的事件类型是 HTMLAnchorElement 的&
MouseEvent ?我有点期待它是一个工会——要么是一个,要么是另一个?
知道如何解决这个问题吗?
解决方案
可能你不应该这样做
您的组件的 props 是隔离代码块的公共 API,因此您不想将其扩展得太远。最好的解决方案是不要将所有链接/按钮道具包含在Button
道具中,而仅包含必要的道具
但如果你必须
问题是打字稿不明白什么是onClick
类型,因为它可能会根据你传递的道具而有所不同。到打字稿出现时props.onClick(execution)
,道具的类型仍然模棱两可。
解决方案
使用你的 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 (...);
}
推荐阅读
- java - 如何使用 Spring WebClient 将 HTTP 请求的执行与 HTTP 响应体的解析分开?
- javascript - 如何在 React 自定义 Hook 中正确调用 useState?
- python - 多处理模块如何提供远程并发?
- flutter - Flutter:如何在手机屏幕上显示来自资产的短文本文件?
- java - 在单元测试中访问实例的私有方法
- c# - 使用 FTDI 创建 UWP 应用程序的问题
- graph - Dijsktra 算法 - 先行者
- javascript - 即使其中有数据,我的数组中的项目也未定义
- javascript - 如何从文件输入中读取文件内容?
- html - 半容器,半容器流体