HTMLInputElement forwardRef doesn't accept name

Viewed 663

Codesandbox.

Here is my input component:

import styled from 'styled-components'
import React, { forwardRef } from 'react'

type Props = {
  err: boolean
  maxWidth: string
}

export const Input = forwardRef<HTMLInputElement, Props>(({ ...rest }, ref) => {
  return <StyledInput {...rest} ref={ref} />
})

const StyledInput = styled.input<Props>``

Here is usage:

<Input name='password' type='password' autoComplete='password' required />

Why name gives me error (as i can see other props have error too):

Type '{ name: string; type: string; autoComplete: string; required: true; }' is not assignable to type 'IntrinsicAttributes & Props & RefAttributes<HTMLInputElement>'.
  Property 'name' does not exist on type 'IntrinsicAttributes & Props & RefAttributes<HTMLInputElement>'.ts(2322)

When default react interface has this prop:

interface HTMLInputElement extends HTMLElement {
    name: string;
    /**
     * Gets or sets a string containing a regular expression that the user's input must match.
     */
}
3 Answers

The first type in forwardRef<HTMLInputElement, Props> only specifies the ref type, so you can't pass the properties inside HTMLInputElement as props.

Instead, you should expand your Props type by adding the HTMLInputElement type as an option.

type Props = {
  err: boolean
  maxWidth: string
} & HTMLInputElement

However, in this case, you will be required to provide all 200-something properties of HTMLInputElement as props to your Input. That's no good, but Typescript has a neat little trick for that. You can use Partial<HTMLInputElement> instead.

type Props = {
  err: boolean
  maxWidth: string
} & Partial<HTMLInputElement>

Now, you'll be required to provide your own defined props (err and maxWidth) and you can optionally provide any property from HTMLInputElement.

Hope this helps.

Here is solution:

interface Props extends React.ComponentPropsWithoutRef<'input'> {
  err?: boolean
  maxWidth?: string
}

You should declare your Props type as below

static propTypes = {
      name: PropTypes.string,
      ...
 }

I hope this will help!

Related