如何使用这种类型或另一种仅基于道具的类型?React Typescript区分并集



我有一个组件:

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>}
</>)
}
  • 有一种基本类型带有道具,这两种类型都有共同点
  • 组件应具有基于给定道具的按钮或链接类型。但如果它有链接,这些道具是首选

打字错误:

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

我不想要的:

  • 我可以通过在基本类型中添加一个类型来解决问题,并根据它们来决定允许使用哪些道具。我想根据道具自动决定

信息:4.5.4 TypeScript Version

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

TS游乐场

// 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
}

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

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

最新更新