reactjs - 如何处理一个重载中存在而另一重载中不存在的属性?

标签 reactjs typescript overloading

我使用 React 16 和 Typescript 3。我创建了一个组件,该组件根据是否设置属性 to 返回按钮或链接。该组件可以获取 toonClick 属性,但不能同时获取两者。

我找到了issue on TypeScript repository这准确地描述了我的问题,它似乎在 2.2 版本中修复了,但以某种奇怪的方式,它不起作用。

为此,我创建了接口(interface)并按如下方式使用它们:

interface GeneralProps {/* whatever here, it works */}
interface LinkProps extends GeneralProps { to: string }
interface ButtonProps extends GeneralProps { 
  onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void 
  // onClick might be as well undefined
}

function Button (props: LinkProps | ButtonProps): JSX.Element {
  const Component: AnyStyledComponent = props.to ? Link : Button
  return (
    <Component to={props.to} onClick={props.onClick}>
      {props.children}
    </Component>
  )
}

或者,我也尝试这样编写这个函数:

function Button (props: LinkProps): JSX.Element
function Button (props: ButtonProps): JSX.Element {
  const Component: AnyStyledComponent = props.to ? Link : Button
  return (
    <Component to={props.to} onClick={props.onClick}>
      {props.children}
    </Component>
  )
}

上面 Button 函数的第一个实现抛出两个错误,第二个实现仅抛出第一个错误:

Property 'to' does not exist on type 'LinkProps | ButtonProps'. Property 'to' does not exist on type 'ButtonProps'.

Property 'onClick' does not exist on type 'LinkProps | ButtonProps'. Property 'onClick' does not exist on type 'LinkProps'.

为了避免错误,我采用了愚蠢的解决方法:

function Button (props: LinkProps | ButtonProps): JSX.Element {
  const properties = Object.keys(props)
  const to = properties.find((el) => el === 'to')
  const Component: AnyStyledComponent = to ? Link : Button
  return (
    <Component {...props}>
      {props.children}
    </Component>
  )
}

但是,这并不能解决我的问题,因为我仍然可以将 toonClick 属性传递给 Button 组件。

我的代码中是否存在某种阻止我实现目标的错误,我应该从不同的角度解决这个问题,还是这根本不可能做到?

最佳答案

感谢 jcalz 发布的帖子,我想出了一个解决方案,它实际上按照我的预期工作。我的解决方案是不同的(我使用接口(interface),而不是类型),但是该线程让我想到使用 never 类型。我之前也使用过它,但是作为必需的属性,然后 typescript 要求传递一个值,当你传递它时, typescript 要求删除它。从不键入的属性必须是可选的。

interface GeneralProps {/* whatever here, it works */}
interface LinkProps extends GeneralProps { 
  to: string
  onClick?: never
}
interface ButtonProps extends GeneralProps { 
  onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void 
  to?: never
}
function Button (props: LinkProps | ButtonProps): JSX.Element { ... }

使用当前的解决方案, typescript 始终会识别类型上存在的两个属性,toonClick,当我通过其中任何一个时都不会抛出错误属性,但当我传递这两个属性时抛出。

关于reactjs - 如何处理一个重载中存在而另一重载中不存在的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54318328/

相关文章:

带有泛型重载的 Java 删除(不是覆盖)

delphi - 如何从DLL导出重载函数?

c++ - 从一个命名空间内部调用在多个命名空间中重载的函数

javascript - 如何从父对象返回子对象数组

javascript - 重新渲染 React props.children

React Hook 中使用 setInterval() 的 Javascript 闭包

d3.js - 在不影响刻度标签的情况下更改 d3 图表轴线的粗细/宽度

javascript - 如何在 Angular 2 应用程序中使用 Phoenix Channels/Sockets?

reactjs - 'string | undefined' 类型的参数不能分配给 'string' 类型的参数。类型 'undefined' 不可分配给类型 'string'

angular - 如何调试 Angular2/Typescript 中的 Observable 值?