facebook / prop-types

Runtime type checking for React props and similar objects
MIT License
4.48k stars 356 forks source link

`.elementType` incompatible with `React.ElementType` #361

Closed SevenOutman closed 2 years ago

SevenOutman commented 2 years ago

Hi, I'm writing my components library in TypeScript and using prop-types in case users use my library with JavaScript. And my TypeScript is complaining that React.ElementType and PropTypes.elementType are not compatible.

Type 'Requireable<ReactComponentLike>' is not assignable to type 'Validator<ElementType<any> | null | undefined>'.
  Types of property '[nominalTypeHack]' are incompatible.
    Type '{ type: ReactComponentLike | null | undefined; } | undefined' is not assignable to type '{ type: ElementType<any> | null | undefined; } | undefined'.
      Type '{ type: ReactComponentLike | null | undefined; }' is not assignable to type '{ type: ElementType<any> | null | undefined; }'.
        Types of property 'type' are incompatible.
          Type 'ReactComponentLike | null | undefined' is not assignable to type 'ElementType<any> | null | undefined'.
            Type 'string' is not assignable to type 'ElementType<any> | null | undefined'.ts(2322)

@types/react version 17.0.3 @types/prop-types version 15.7.4

It can be reproduced with this simple demo on CodeSandbox https://codesandbox.io/s/vibrant-burnell-xhksw?file=/src/Button.tsx

interface ButtonProps {
  as?: React.ElementType;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (props, ref) => {
    return null;
  }
);

Button.propTypes = {
  as: PropTypes.elementType
};
ljharb commented 2 years ago

When the types are wrong, the most likely reason is that the types are wrong. A distant second is that the implementation is wrong.

In this case, if React and elementType are in sync, then it's the DT package that's got the issue ("nominalTypeHack" looks fishy to me)

SevenOutman commented 2 years ago

Hi @ljharb , yes I think it's the types that are incompatible. @types/react regards HTML element tags as union of a limited range of values, while @types/prop-types regards it as plain string. Is this repo the right place for raising issues for types?

ljharb commented 2 years ago

The place to look for correctness js never the types - what does react do? Whatever that is, the types should match.

ljharb commented 2 years ago

No, the DefinitelyTyped repo is basically always the right place for types (it’s best when even packages authored in TS don’t ship their own types, because it conflates the semver of the types and the actual important part, the implementation)

SevenOutman commented 2 years ago

Alright. Just opened a thread in the DT repo https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/57143