Next.js Typescript Project Custom Link Button Proptype

Viewed 42

My project has a custom Button component and a NextLink wrapper that passes the href down to the button. I want to combine these two components for cleanliness' sake, but something goes wrong when I combine the props for each. I am unable to spread rest in the prop destructuring statement. I get a TypeScript error saying:

Rest types may only be created from object types.ts(2700)

Whenever I remove (or comment out) size: 'xs' | 's' | 'm' | 'l' | 'xl', the error disappears. So my question is obviously, is something wrong with my size type? Is this a bug? Component follows.

import NextLink, { LinkProps } from 'next/link'
import { HTMLProps, FC } from 'react'
import { GlobalColorsType } from '../../types'
import Button from './Button'

type ButtonProps = {
  type: GlobalColorsType
  size: 'xs' | 's' | 'm' | 'l' | 'xl'
  onClick: () => void
  className?: string
  id?: string
  style?: any
}

type LinkButtonProps = ButtonProps & LinkProps & HTMLProps<HTMLAnchorElement>

const LinkButton: FC<LinkButtonProps> = ({
  as,
  children,
  href,
  replace,
  scroll,
  shallow,
  passHref,
  ...rest
}) => (
  <NextLink
    as={as}
    href={href}
    passHref={passHref}
    replace={replace}
    scroll={scroll}
    shallow={shallow}
  >
    <a {...rest}>
      <Button ...ButtonProps/>
    </a>
  </NextLink>
)

export default LinkButton
1 Answers

The HTMLProps type includes all the possible attributes that every HTML element can have. You should use AnchorHTMLAttributes instead, which provides anchor-specific props, and further narrows down the props type.

type LinkButtonProps = ButtonProps & LinkProps & AnchorHTMLAttributes<HTMLAnchorElement>

If the above doesn't cover all the attributes you need for the anchor element, you can use ComponentProps<'anchor'> instead.

type LinkButtonProps = ButtonProps & LinkProps & ComponentProps<'anchor'>
Related