eslint-plugin-react icon indicating copy to clipboard operation
eslint-plugin-react copied to clipboard

Typescript "'className' is missing in props validation" despite being defined

Open awwong1 opened this issue 3 years ago • 6 comments

Description

I am observing 'className' is missing in props validation despite it being correctly specified in the type definition.

  • React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
  • https://github.com/DefinitelyTyped/DefinitelyTyped/blob/90f13b6b5e4ee2db30044f960327e17ed3ef3338/types/react/index.d.ts#L1854
    • React.HTMLAttributes<HTMLInputElement>.className?: string | undefined

Versions

    "@types/react": "^18.0.0",
    "eslint": "^8.8.0",
    "eslint-plugin-react": "^7.28.0",
    "react": "^18.0.0",
    "typescript": "^4.5.5"

Example

import React from 'react'

const classNames = (...classes: (false | null | undefined | string)[]) =>
  classes.filter(Boolean).join(' ')


export const Input = (
  props: React.DetailedHTMLProps<
    React.InputHTMLAttributes<HTMLInputElement>,
    HTMLInputElement
  >
) => (
  <input
    {...props}
    className={classNames(
      'class-a',
      'class-b',
      // eslint-disable-next-line react/prop-types
      props.className
    )}
  />
)

Expected behaviour

The eslint-disable-next-line should not be necessary. I can also workaround this by adding in & { className?: string } into the type definition of props.

  props: React.DetailedHTMLProps<
    React.InputHTMLAttributes<HTMLInputElement>,
    HTMLInputElement
  > & { className?: string }

awwong1 avatar May 08 '22 17:05 awwong1

Seems like React.DetailedHTMLProps is a thing we don't have any knowledge of, and we'd have to hardcode support for (probably React.InputHTMLAttributes as well).

ljharb avatar May 08 '22 20:05 ljharb

I have the same problem

type TDelIconProps = React.HTMLProps<HTMLDivElement>;

const DelIcon: React.FC<TDelIconProps> = ({className, ...rest}) => (
    <div className={classNames('del flex-center', className)} {...rest}>
        <i className="iconfont icon-del f12" />
    </div>
);

ESLint: 'className' is missing in props validation(react/prop-types)

Versions

eslint:7.32.0
eslint-plugin-react:7.30.0

lokve avatar May 23 '22 06:05 lokve

It seems weird to me, but this workaround, using an interface and extending DetailedHTMLAttributes, seems to work:

interface InputProps  extends React.DetailedHTMLProps<
  React.InputHTMLAttributes<HTMLInputElement>,  
  HTMLInputElement
> {}

export const Input = (
  props: InputProps
) => (
  // your code
);

DerPipo avatar Dec 05 '22 01:12 DerPipo

Still broken in 7.33.2

rwb196884 avatar Nov 08 '23 13:11 rwb196884

@rwb196884 its not broken, it’s just not something we support yet.

ljharb avatar Nov 08 '23 15:11 ljharb

If you import directly from React the error message goes away.

Works:

import type { HTMLAttributes } from "react"
import { cn } from "../../lib/utils"

export function Heading({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
  return <div className={cn("font-semibold text-lg", className)} {...props} />
}

Does not work:

import React from "react"
import { cn } from "../../lib/utils"

export function Heading({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
  return <div className={cn("font-semibold text-lg", className)} {...props} />
}

divmgl avatar Mar 27 '24 01:03 divmgl