8

I've tried to use "Link" element as my custom react component that I modified it with typescript to add some more facilities but everytime used it in my project it's made me to write a property with the name of props which its included some other properties :

below line is my typescript runtime error :

Type '{ link: string; title: string; }' is missing the following properties from type 'DetailedReactHTMLElement<{ onMouseEnter?: MouseEventHandler<Element> | undefined; onClick?: MouseEventHandler<Element> | undefined; href?: string | undefined; ref?: any; }, HTMLElement>': type, ref, props, keyts(2739)

I wrote my custom react component :

import style from "./Button.module.css";
import Link from "next/link";
export const Button: React.FunctionComponent<
  React.DetailedReactHTMLElement<
    {
      onMouseEnter?: React.MouseEventHandler<Element> | undefined;
      onClick?: React.MouseEventHandler;
      href?: string | undefined;
      ref?: any;
    },
    HTMLElement
  > & {
    title?: string;
    link?: string;
  }
  > = ({ title, children, link, ...rest }) => (
  <Link href={`${link}`} {...rest}>
    {title ?? children}
  </Link>
  );

when I using it somewhere as my Button :

<Button link={exploreLink} title="Explore Event" />

2 Answers 2

16

A few points to note so you know what's going on...

  • Your losing all Next/link attributes (as, shallow, passHref,replace , etc.)
  • You are missing the required anchor tag inside of next/link
  • Next link has its own type - LinkProps
  • link as a prop name is confusing as the standard is href and it's already included
  • LinkProps hold all standard next/link props;
  • FC is react's built in functional component - adds children prop and sets return to a ReactElement|null
  • HTMLProps are react's built in synthetic events and react specific props
  • HTMLAnchorElement adds all standard html props like className, title, etc.
import NextLink, { LinkProps } from 'next/link';
import { HTMLProps, FC } from 'react';

const LinkButton: FC<LinkProps & HTMLProps<HTMLAnchorElement>> = ({
  as, children, href, replace, scroll, shallow, passHref, ...rest
}) => (
  <NextLink
    as={as}
    href={href}
    passHref={passHref}
    replace={replace}
    scroll={scroll}
    shallow={shallow}
  >
    <a {...rest}>
      {children}
    </a>
  </NextLink>
);

If your adding custom props you could make your own type

import { MouseEvent, HTMLProps, FC } from 'react';

type MyLink = {
 customProp?: string;
} & LinkProps & HTMLProps<HTMLAnchorElement>;

LinkButton: FC<MyLink> = ({ onClick, ...rest }) => {
 const customClick = (event: MouseEvent<HTMLAnchorElement>)={
 }
 ....
}

Usage

<LinkButton href={exploreLink} title="Explore Event" />
Sign up to request clarification or add additional context in comments.

3 Comments

Wow this is amazing respond , well I've changed my accepted answer
Great answer. One update is now HTMLProps<HTMLAnchorElement> should be replaced with Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof LinkProps> & LinkProps
@Gabe that is clever
1

You don't need React.DetailedReactHTMLElement; try:

React.FunctionComponent<
    {
      onMouseEnter?: React.MouseEventHandler<Element>;
      onClick?: React.MouseEventHandler;
      href?: string;
      ref?: any;
    }
  & {
    title?: string;
    link?: string;
  }
>

2 Comments

that's it and for final question how about the className , how should I add this property to my custom button while there's not a property for add a class name to "Link" Next.Js

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.