TypeScript error: Parameter 'e' implicitly has 'any' type in Link component
The issue is that your handleClick function parameter e doesn't have a type annotation, and with "strict": true in your tsconfig, TypeScript requires explicit types.
The Quick Fix:
Add a type to the e parameter:
function handleClick(e: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>) {
if (e.type === 'click' || (e as React.KeyboardEvent).key === 'Enter') {
onClick?.(e as React.MouseEvent<Element, MouseEvent>)
}
}Better Approach - Separate Handlers:
Since your onClick prop only accepts MouseEvent, it's cleaner to separate the handlers:
const Link: React.FC<Props> = ({ children, href, className, target, rel, onClick }) => {
function handleKeyPress(e: React.KeyboardEvent<Element>) {
if (e.key === 'Enter') {
onClick?.(e as any as React.MouseEvent<Element, MouseEvent>)
}
}
return (
<NextLink href={href}>
<a
className={className}
target={target}
rel={rel}
{...(onClick
? {
onClick,
onKeyPress: handleKeyPress,
role: 'link',
tabIndex: 0,
}
: {})}
>
{children}
</a>
</NextLink>
)
}Modern Next.js Note:
If you're using Next.js 13+ with the App Router, you don't need the <a> tag inside <NextLink> anymore. You can simplify to:
<NextLink
href={href}
className={className}
target={target}
rel={rel}
onClick={onClick}
>
{children}
</NextLink>This eliminates the need for the keyboard handler complexity since Next.js handles accessibility internally. This is much cleaner and avoids the TypeScript issues altogether!
Show original thread4 replies
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.