我正在努力键入以下动态按钮组件,可以处理链接或onClick事件。下面是我现在尝试重构为TypeScript的组件的一个简化片段:
import React from 'react'
import { Link } from 'react-router-dom'
type Props = {
children: React.ReactNode,
} & (
{
to: string,
type: undefined,
onClick: undefined,
} | {
to: undefined,
type: 'button' | 'submit',
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void,
}
)
export default function Button(props: Props) {
const { children, to } = props
const TagName = to ? Link : 'button'
return (
<TagName {...props}>
{children}
</TagName>
)
}
显示如下错误:
Type '{ children: ReactNode; to: string; onClick: undefined; } | { children: ReactNode; to: undefined; onClick: (event: MouseEvent<HTMLButtonElement, MouseEvent>) => void; }' is not assignable to type 'IntrinsicAttributes'.
Type '{ children: ReactNode; to: string; onClick: undefined; }' has no properties in common with type 'IntrinsicAttributes'.
我想我必须定义TagName的类型,但我不能找出正确的类型。任何建议吗?
是Link组件类型导致了这个问题,因为我可以在没有它的情况下让它工作。
Typescript不允许你这样做,因为你的组件道具与button
&link
的道具类型声明。这样就有了一个可以区分button
道具和Link
道具的共同字段,在这种情况下使用Props
的type
属性。
import { Link } from 'react-router-dom'
type Props = {
children: React.ReactNode
} & (
| {
to: string
type: 'url'
}
| {
type: 'submit' | 'button'
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
}
)
export default function Button(props: Props) {
if (props.type === 'url') {
return <Link {...props} />
}
return <button {...props} />
}