I’ve tried to make the ‘…rest’ prop be of a certain type. Either LinkProps or NavLinkProps.
It works correctly, when $type: "navLink"
then it has access to fields specified in NavLinkProps, and when $type: "link"
then it doesn’t have access to them anymore. Just as expected. However, i’m still wondering – is this the correct way to implement something like this? Or maybe there are better ways to do it?
import { Link, LinkProps, NavLink, NavLinkProps } from "react-router-dom";
import styled, { css } from "styled-components";
type RegularLinkProps = {
$type: "link";
} & LinkProps;
type NavigationalLinkProps = {
$type: "navLink";
} & NavLinkProps;
const StyledCustomLink = styled(Link).attrs<
{ $type: "link" | "navLink" } & (LinkProps | NavLinkProps)
>(({ $type }) => ({
as: $type === "link" ? Link : NavLink,
}))`
display: flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
position: relative;
overflow: hidden;
text-decoration: none;
transition: color 0.2s, fill 0.2s;
${({ $type }) =>
$type === "navLink" &&
css`
padding: 3rem;
`};
&::after {
content: "";
position: absolute;
left: -100%;
top: calc(100% - 2px);
width: 100%;
height: 2px;
background-color: var(--color-dark-grey);
transition: transform 0.2s;
}
&:hover {
color: var(--color-dark-grey);
fill: var(--color-dark-grey);
&::after {
transform: translateX(100%);
}
}
`;
export function CustomLink({
children,
$type,
...rest
}: RegularLinkProps | NavigationalLinkProps) {
return (
<StyledCustomLink $type={$type} {...rest}>
{children}
</StyledCustomLink>
);
}