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

`react/prop-types` validation using typescript

Open vicasas opened this issue 3 years ago • 1 comments

Summary

In a Typescript project it would be very useful if react/prop-types could validate that apart from the TS definitions the PropTypes definitions are made, so that both work together.

This would help a lot to achieve a better development experience in cases where it is required, the differences between the two must be taken into account since they serve different purposes.

Typescript validates types at compile time, while PropTypes are checked at runtime. the latter is very useful when testing how components interact with external data etc.

Current behavior:

Just adding the typescript type to it stops throwing a PropTypes error.

interface HelloProps {
  name: string
  lastname: string
}

export default function Hello({ name, lastname }: HelloProps) {
  return (
    <div>
      Hello {name} {lastname}
    </div>
  )
}

Expected behavior:

With the new rule enabled this should throw a PropTypes error.

Incorrect code

interface HelloProps {
  name: string
  lastname: string
}

export default function Hello({ name, lastname }: HelloProps) {
  return (
    <div>
      Hello {name} {lastname}
    </div>
  )
}
interface HelloProps {
  name: string
  lastname: string
}

export default function Hello({ name, lastname }: HelloProps) {
  return (
    <div>
      Hello {name} {lastname}
    </div>
  )
}

Hello.propTypes = {
  name: PropTypes.string.isRequired,
}
interface HelloProps {
  name: string
  lastname: string
}

export default function Hello({ name, lastname }: HelloProps) {
  return (
    <div>
      Hello {name} {lastname}
    </div>
  )
}

Hello.propTypes = {
  name: PropTypes.number.isRequired,
  lastname: PropTypes.bool.isRequired,
}

Correct code

interface HelloProps {
  name: string
  lastname: string
}

export default function Hello({ name, lastname }: HelloProps) {
  return (
    <div>
      Hello {name} {lastname}
    </div>
  )
}

Hello.propTypes = {
  name: PropTypes.string.isRequired,
  lastname: PropTypes.string.isRequired,
}
interface HelloProps {
  name: string
  lastname?: string
}

export default function Hello({ name, lastname = "" }: HelloProps) {
  return (
    <div>
      Hello {name} {lastname}
    </div>
  )
}

Hello.propTypes = {
  name: PropTypes.string.isRequired,
}

Idea:

In the options of the react/prop-types rule, a new option could be added to enable this behavior.

vicasas avatar Sep 16 '22 03:09 vicasas

This isn't something that's possible with static analysis - propType functions are massively more broad than just what's in React.PropTypes, and only the types of the prop-types package are statically knowable.

I completely agree that any component without propTypes is suffering a huge loss of protection, that TS is incapable of fully replacing - but i don't think there's anything except typechecked tests (that actually run) to keep props types and propTypes in sync.

ljharb avatar Sep 16 '22 04:09 ljharb