Definitelytyped: [@types/react] "Types of property 'render' are incompatible" using intersection type with 15.0.28

Created on 13 Jun 2017  ยท  8Comments  ยท  Source: DefinitelyTyped/DefinitelyTyped

  • [X] I tried using the @types/react 15.0.28 package and had problems.
  • [X] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [X] I have a question that is inappropriate for StackOverflow. (Please ask any appropriate questions there).
  • [X] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @johnnyreilly @ericanderson @digiguru @pzavolinsky @bbenezech

Version 15.0.27 was able to correctly determine the type React.ComponentClass<P> that results from wrapping the Component in this function, but in version 15.0.28, the <Component ... /> line gives me the following error:

TS2605:JSX element type 'Component<P & IWithPersonalizationProps, ComponentState>' is not a constructor function for JSX elements.
  Types of property 'render' are incompatible.
    Type '() => false | Element' is not assignable to type '{ (): false | Element; (): Element; (): Element; (): Element; (): Element; (): Element; }'.
      Type 'false | Element' is not assignable to type 'Element'.
        Type 'false' is not assignable to type 'Element'.
import * as React from "react";

export interface IWithPersonalizationProps {
    name: string;
}

type HOC<PWrapped, PHoc> = React.ComponentClass<PWrapped & PHoc> | React.SFC<PWrapped & PHoc>;

export function withPersonalization<P, S>(Component: HOC<P, IWithPersonalizationProps>): React.ComponentClass<P> {

    class C extends React.Component<P & IWithPersonalizationProps, S> {

        public render(): JSX.Element {

            const {name, ...rest} = this.props as any;
            // ... todo: get the name from somewhere, e,g. the redux store.

            // the error occurs in the JSX component below:
            return ( 
                <Component name={name} {...rest} />
            );
        }
    }
    return C;
}

export default withPersonalization;

The purpose of this function is to wrap an arbitrary Component that implements IWithPersonalizationProps, and delegate the handling of the name prop to the withPersonalization wrapper. All the other props declared by Component are passed through, and the resulting component is typed with React.ComponentClass<P>. P therefore would be the type of the props of Component, minus the props described by IWithPersonalizationProps. The wrapped component might look like this:

interface ITestPersonalizedComponentOwnProps {
   greeting: string;
}

type TestPersonalizedComponentProps = 
        ITestPersonalizedComponentOwnProps 
        IWithPersonalizationProps &

class TestPersonalizedComponent extends React.Component<TestPersonalizedComponentProps, {}> {
    public render(): JSX.Element {
        return (<div>{this.props.greeting},, {this.props.name}</div>);
    }
}

Most helpful comment

@DeividasBakanas @GiedriusGrabauskas Happened to me when I upgraded @types/react but some other package depended on it and yarn chose to keep both old and new versions.
I fixed it with rm -rf node_modules & yarn which then outputted a proper lock file with only one version.

All 8 comments

PR: #17025

Same with flux container.

JSX element type 'Component<{}, ComponentState>' is not a constructor function for JSX elements.
  Types of property 'render' are incompatible.
    Type '() => false | Element | null' is not assignable to type '{ (): false | Element | null; (): Element | null; }'.
      Type 'false | Element | null' is not assignable to type 'Element | null'.
        Type 'false' is not assignable to type 'Element | null'.

Component implementation:
FluxContainer.d.ts#L45

@vbfox @vsiao @johnnyreilly

@DeividasBakanas could you explain more about this problem?

I had this problem with an error @GiedriusGrabauskas mentioned above.

The problem was that I had two files of React type definitions in my project (had to find this out in the hard way...). These type definitions files appeared to have different versions so it caused this error.

Possible solution is to have typeRoots property declared in a tsconfig.json with a root folder of type definitions or / and exclude all other possible type definitions files sources using exclude property to have a single source of type definitions files.

@DeividasBakanas @GiedriusGrabauskas Happened to me when I upgraded @types/react but some other package depended on it and yarn chose to keep both old and new versions.
I fixed it with rm -rf node_modules & yarn which then outputted a proper lock file with only one version.

Cleaning node_modules out works for me. So it's an related issue with transitive dependency management with yarn.

I upgraded five or six other packages separately and had similar dependency problems, but with widely varying errors. All of them were solved by wiping out node_modules.

I'm having the same issue with:

    "@types/react": "16.0.5",
    "@types/react-dom": "15.5.4",

Cleaning node_modules didn't do anything for me. I'm not sure what I'm missing.
@DeividasBakanas you wrote that you found out that you had conflict type declaration present, how did you find out? It sounds like I could have the same issue as well.

@wcandillon @types/[email protected] has a dependency of @types/react@*, while later versions are more restrictive (e.g. @types/[email protected] specifies @types/react@^15. Check your yarn.lock to ensure that you're not resolving to two incompatible major versions of @types/react.

starts writing JSX on the same line as the return statement.
Example
return (<Component name={name} {...rest} /> );

instead

return (
<Component name={name} {...rest} />
 );

I ran into this issue when upgrading @types/react from 16.7.13 to 16.7.17 - I kept getting this error:

TS2605: JSX element type 'ReactElement<any> | null' is not a constructor function for JSX elements.
  Type 'ReactElement<any>' is not assignable to type 'Element'.

I thought it was due to the changes introduced in @types/react 16.7.14 (PR). But it turns out that my repo had multiple versions of @types/react. yarn list @types/react returned:

โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ”œโ”€ @types/[email protected]
โ”‚  โ””โ”€ @types/[email protected]
โ””โ”€ @types/[email protected]

I fixed this by updating resolutions option on package.json:

// package.json
{
  ...

  "resolutions": {
    "@types/react": "16.7.17",
    "@types/react-dom": "16.0.11"
  }
}

Thanks @azu for the pointer (in Japanese).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

variousauthors picture variousauthors  ยท  3Comments

victor-guoyu picture victor-guoyu  ยท  3Comments

Loghorn picture Loghorn  ยท  3Comments

lilling picture lilling  ยท  3Comments

Zzzen picture Zzzen  ยท  3Comments