Есть следующий компонент кнопки, который я постарался максимально упростить для примера:
import React from 'react'
import { Link } from 'react-router-dom'
type ButtonProps = (
& React.ComponentPropsWithoutRef<'button'>
& React.AriaAttributes
& { href?: never }
)
type AnchorProps = (
& Omit<LinkProps, 'to'>
& React.AriaAttributes
& { href: string }
)
type OverloadedComponent = (
& React.FunctionComponent<ButtonProps>
& React.FunctionComponent<AnchorProps>
)
const isAnchor = (props: ButtonProps | AnchorProps): props is AnchorProps => 'href' in props
const Button: OverloadedComponent = (props) => {
if (isAnchor(props)) {
const { href, ...linkProps } = props
return (
<div className="button">
<Link className="control" to={href} {...linkProps } />
</div>
)
}
return (
<div className="button">
<button className="control" {...props} />
</div>
)
}
export default Button
Компонент принимает в качестве параметров либо
ButtonProps
, либо
AnchorProps
.
1. Если я передаю ему параметр
type
- он подсказывает значения
button
,
reset
и
submit
;
2. Если я передаю ему параметр
onClick
без передачи
href
- то событие происходит именно для
HTMLButtonElement
, а в противном случае для
HTMLAnchorElement
;
Но это реализация компонента с помощью
FunctionComponent
, но сколько я ни пытался - не получается это переписать на
ForwardRefRenderFunction
, чтобы передаваемые
ref
зависели от
Props
. Я примерно понимаю что это должно как-то реализовываться с помощью дженериков, но решение мне в голову так и не пришло.