30

I have a React Typescript application that won't compile. Many components have a render method that is typed to return React.ReactNode or React.ReactElement. On compile, many errors similar to the following are reported:

TS2786: 'MessagesWidget' cannot be used as a JSX component.
 Its instance type 'MessagesWidget' is not a valid JSX element.
 The types returned by 'render()' are incompatible between these types.
 Type 'React.ReactNode' is not assignable to type 'import("/home/node/app/node_modules/@types/react-calendar/node_modules/@types/react/index").ReactNode'.

Why is the compiler expecting ReactNode as defined by the types bundled with react-calendar? I do have @types/react-dom installed as a dev dependency.

Other information that might be relevant:

  1. This project was compiling until a couple of days ago and there were no code changes when the compile started failing, so I suspect that a package update triggered this (even if that's not the root cause). The only dependencies that were updated in the time window when the compile started failing were @types/react and @types/react-dom. Rolling these packages back to an older version did not fix the issue, however.
  2. Changing my components render methods to return JSX.Element removes the compiler error, but there are third party components in the application where this is not possible.
choz
  • 17,242
  • 4
  • 53
  • 73
andypaxo
  • 6,171
  • 3
  • 38
  • 53
  • `React.ReactNode` is definitely the correct return type for the `render` method of react components, so this is pretty strange. But without [a minimal example,](https://stackoverflow.com/help/minimal-reproducible-example) I'm not sure we can be of much help. – Alex Wayne Apr 11 '22 at 17:00
  • 2
    I had the exact same issue pop up today, except my import is from `react-dom` or `react-transition-group`. There's definitely something wrong with the types package. I just added `@ts-ignore` in the meantime. – Anthony Ma Apr 11 '22 at 23:38
  • We are seeing this on our projects. I'll try hard fixing @types to older version. – gimp3695 Apr 13 '22 at 04:15

15 Answers15

56

I have a solution, it seems that there are a ton of breaking changes in the 18.0.1 type definitions.

Like you, I could not solve it by rolling back to earlier versions, but investigation lead me to discover that this was because 'react-router' among others was bringing in the '18.0.1' version.

to get around this, I added the following to my package.json

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

Then I cleared my node-modules, and my package cache and then re-ran yarn to pull fresh packages.

The resolutions section is for yarn (which I use). and I think you can use 'overrides' instead of 'resolutions' if you are using NPM.

npm version should >= 8 https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides

and delete package-lock.json before npm i.

lazy
  • 3
  • 2
DocCaliban
  • 784
  • 6
  • 13
28

Error TS2786 often comes from a mismatch in @types/react.

When you have libraries that are dependent on a specific version of @types/react (i.e. v17.0.47) and you have other libraries working with a different major version of @types/react (i.e. v18.0.14), then this can cause compatibility issues when using React.ReactNode or JSX.Element. The type JSX.Element is usually returned by a React Function Component.

You can solve the problem by streamlining your dependencies on @types/react, so that these follow the same major version. You can find all libraries depending on @types/react in your project by executing npm explain @types/react (when a package-lock.json file is present) or yarn why @types/react (when a yarn.lock file is present).

In your specific case there seems to be a dependency from @types/react-calendar to @types/react. Your problem seems to be that there are other dependencies in your project using a different version of @types/react. Maybe you even have a direct dependency on @types/react where the exact version number is different from the @types/react version required by @types/react-calendar.

Here is a video that shows how to inspect the applied version of @types/react in your own project.

Benny Code
  • 51,456
  • 28
  • 233
  • 198
  • 2
    Mismatch in `react` and `@types/react` versions it is. Thanks! – andr1o Jul 05 '22 at 08:42
  • 1
    This doesn't explain how to fix the issue, which would be to actually run `npm dedupe` – SudoPlz Sep 29 '22 at 13:36
  • You could use `npm dedupe` or you could use `resolutions` to force a resolution if there's a hard dependency coming in from an over-zealous package.json. – Zack Dec 18 '22 at 20:39
  • When using `yarn` then the `dedupe` functionality is already applied: https://classic.yarnpkg.com/en/docs/cli/dedupe - If this doesn't help, you would have to inspect where the typings come from manually by using `yarn why` or `npm explain`. – Benny Code Dec 19 '22 at 22:06
  • I had to update the `@types/react` version in the `resolutions` block. – Sufian Aug 22 '23 at 17:47
9

This can occur when returning children:

export const Component = ({ children }) => {
    //...do stuff
    return children
}

To fix, wrap in a fragment:

return <>{children}</>

I believe this is because children may be an array of elements and we are only allowed to return a single element. The usual message for this kind of error is:

JSX expressions must have one parent element.

chantey
  • 4,252
  • 1
  • 35
  • 40
4

This issue comes with mismatch in @types/react versions TS2786

Fix it with npm dedupe or yarn dedupe

Vikas Sharma
  • 685
  • 8
  • 18
4

After update React native from 0.66.3 to 0.70.6 I faced same issue. I solved the problem by changing the "resolutions" in the package.json

"resolutions": {
    // "@types/react": "^17" remove this
    "@types/react": "^18.0.8" //adding this
 },
  // After Change remove node_modules 
  // run npm i OR yarn

 
 
Younis Rahman
  • 637
  • 5
  • 13
3

If there's a yarn user wandering around; who had this issue after doing a react/react-native version upgrade recently; just delete the existing yarn.lock file & the node_modules folder and run yarn install again is what worked for me. :)

  • This worked for me for react web app, deleted node_modules and yarn.lock and re-installed everything and all the warnings were resolved – just-be-weird Aug 26 '23 at 08:04
1

None of the answers above solved my case for the same typescript error TS2786
how I get it work is update tsconfig.json

from

{
  "compilerOptions": {
    "preserveSymlinks": true,
    ...

to

{
  "compilerOptions": {
    "preserveSymlinks": false,
    ...

or just simply remove it

Seeliang
  • 2,321
  • 1
  • 13
  • 18
  • For me, setting to to `true` actually fixed the error. There's an github issue similar to this: https://github.com/pnpm/pnpm/issues/3671 – arian Jan 09 '23 at 13:54
1

I resolved this issue by changing ``jsx: 'react' in tsconfig.json into jsx:react-jsx

greeneley
  • 87
  • 7
0

The problem is because react-route v18 does not support react-virtualized and it should be downgraded.

So the simple way is to downgrade your route as below:

"@types/react": "17.0.0",
"@types/react-dom": "17.0.0"

Then, your app should work properly.

Rasikh
  • 5
  • 1
  • 2
0

Just add the latest version of react and react-dom in package.json and run below command to re-install react and react-dom

Here , while posting this answer, latest version of react and react-dom is 18.

Steps-

  1. Remove package-lock.json file of your proect
  2. Open package.json of your project.
  3. replace react and react-dom version
"@types/react": "^18",

"@types/react-dom": "^18"

4.Run command

npm install --save-dev @types/react @types/react-dom

Done. It resolved my issue.

Preeti
  • 421
  • 5
  • 14
0

I was facing the same issue about this error. I add the below code to my package.json file and got resolved.

"resolutions": {
  "@types/react": "17.0.2",
  "@types/react-dom": "17.0.2",
  "graphql": "^16.5.0"
},
Hammad Hassan
  • 606
  • 7
  • 20
0

my one got solved after I fixed the RETURN statement of my child component

I had in there:

return; <form></form>

changed to:

return (<form></form>)
fruitloaf
  • 1,628
  • 15
  • 10
0

If you previously had a resolution for react 17:

"resolutions": {
    "@types/react": "^17.0.0"
 },

it generates an entry in package-lock/yarn lock that won't be removed when you update. So you need to remove this resolution and the yarn lock entry. It looks like this:

"@types/react@*", "@types/react@17.0.21", "@types/react@^17":
  version "17.0.21"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.21.tgz#069c43177cd419afaab5ce26bb4e9056549f7ea6"
  integrity something
  dependencies:
    "@types/prop-types" "*"
    "@types/scheduler" "*"
    csstype "^3.0.2"

Removing both and running install again should solve your problem

Roberto Yoc
  • 461
  • 2
  • 7
0

If you didn't add @types/react, please add it first by:

yarn add --dev @types/react
Ethan.Li
  • 31
  • 3
0

I will tell about the react-native project. All these answers didn't help me. But I found out the reason for this issue in my project. I forgot to fill "types" parameter in tsconfig.json.

Adding

"types": ["react-native", "jest"]

helped me. Cheers!