TypeScript error: Parameter 'e' implicitly has 'any' type in Link component

4 replies
Last updated: Nov 29, 2025
Hi, dose anyone know what i'm doing wrong here?

import React from 'react'
import NextLink from 'next/link'

interface Props {
  children: Array<JSX.Element | string | null> | JSX.Element | string | null
  className?: string
  href: string
  target?: string
  rel?: string
  onClick?: (event: React.MouseEvent<Element, MouseEvent>) => void
}

const Link: React.FC<Props> = ({ children, href, className, target, rel, onClick }) => {
  function handleClick(e) {
    if (e.type === 'click' || e.key === 'Enter') {
      onClick?.(e)
    }
  }

  return (
    <NextLink href={href}>
      <a
        className={className}
        target={target}
        rel={rel}
        {...(onClick
          ? {
            onClick,
            onKeyPress: handleClick,
            role: 'link',
            tabIndex: 0,
          }
          : {})}
      >
        {children}
      </a>
    </NextLink>
  )
}

export default Link
i'm getting this error:
TS7006: Parameter 'e' implicitly has an 'any' type.
When i'm importing the '../Link' to the hero post the link will not work anymore.

this is my tsconfig.json:

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "preserveConstEnums": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext",
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

AI Update

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 thread
4 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.

Was this answer helpful?