【问题标题】:How to use either this type or another based on props only? React Typescript Discriminating Unions如何仅基于道具使用这种类型或另一种类型? React Typescript 判别工会
【发布时间】:2022-01-26 02:46:33
【问题描述】:

我有一个组件:

type Base = {
    color: string
}

type Button = {
    to: string
} & Base

type Link = {
    link: string
    linkNewTab: boolean
} & Base

type ComponentProps = Button | Link 

export const Button: React.FC<ComponentProps> = (props) => {
    return (<>
        {props.link ? <Link newTab={props.linkNewTab}>...</Link> : props.to && <Button>...</Button>}
    </>)
}
  • 有一个带有 props 的基本类型,这两种类型都有共同点。
  • 根据给定的道具,组件应该具有 Button 或 Link 类型。但如果它有链接,这些道具是首选。

打字稿错误:

Property 'link' does not exist on type 'PropsWithChildren<ComponentProps>'.
  Property 'link' does not exist on type '{ to: string; } & Base & { children?: ReactNode; }'.ts(2339)

我不想要的:

  • 我可以通过向 Base 类型添加类型并决定允许使用哪些道具来解决问题。我想根据道具自动决定。

信息:4.5.4 TypeScript Version

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    问题是您试图访问可能不存在的属性的值。相反,您可以在尝试访问其值之前检查该 property 是否存在于对象中(通过使用in 运算符)。这也会歧视工会:

    TS Playground

    // instead of this:
    if (props.link) {}
    //        ^^^^
    // Property 'link' does not exist on type 'Button | Link'.
    //   Property 'link' does not exist on type 'Button'.(2339)
    
    // prop in obj
    if ('link' in props) {
      props.color // ok
      props.link // ok
      props.linkNewTab // ok
    }
    else {
      props.color // ok
      props.to // ok
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用in 运算符检查link 属性是否存在。这将在不访问属性的情况下缩小类型,因此打字稿将允许它:

      <>
        {"link" in props ? (
          <Link newTab={props.linkNewTab}>...</Link>
        ) : (
          "to" in props && <Button>...</Button>
        )}
      </>
      

      【讨论】:

        猜你喜欢
        • 2022-01-19
        • 2020-08-21
        • 2019-05-24
        • 1970-01-01
        • 2022-11-24
        • 2018-12-08
        • 1970-01-01
        • 2021-04-18
        • 2021-01-24
        相关资源
        最近更新 更多