'react 18 typescript types in package.json

Im trying to upgrade my react 17 to 18

"@types/react": "???????",
"@types/react-dom": "????????",
"react": "^18.0.0",
"react-dom": "^18.0.0",

What should I put in @types/react and @types/react-dom ?
Thanks



Solution 1:[1]

I used Create React App to generate a new TypeScript project and take a look at the dependencies, since I was striking out with the recommendation of removing @types/react and @types/react-dom. That was not fun.

I ended up installing these types:

"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",

Then I could use the following to mount my app in index.tsx:

import React from 'react';
import { createRoot } from 'react-dom/client';
....
const container = document.getElementById('root');
// OH BOY, container can be null but createRoot can't handle this...
if (!container) {
   throw "Can't instantiate";
}
const root = createRoot(container);
root.render(
   <React.StrictMode>
   <App />
   </React.StrictMode>
);

Yes, there is a problem with the current typescript type where it could receive a null, and you have to guard it with an if / throw check... Or do a ts-ignore.

I'm hoping that gets fixed somehow. But anyway, it's 1AM here and I finally was able to get my app working with React 18 and Typescript using this hack.

Solution 2:[2]

At the time I write this, the React 18 types don't appear to be finished yet (see tweet from maintainer). There are former "@next" versions of React 18 types, but they don't match the React 18 release and probably shouldn't be used. Sit tight and they'll likely be finished/released in the coming days.

Solution 3:[3]

while react team working on the new types release, if you want to test it out you can keep the old "@types/react": "^17.0.40" and "@types/react-dom": "^17.0.13" types version, and inside the index.tsx after updating react and react-dom to version 18.0.0 you need first to import ReactDOM from react-dom/client and then create the root element from the element id=root using createRoot and then use .render to render the content of the <App/> component inside the created root element like this:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

let root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);

root.render(
  <React.StrictMode>
      <App />
  </React.StrictMode>,
);

Solution 4:[4]

Looks like @types/react and @types/react-dom are now on v18. Here's how I upgraded:

  • uninstall both those packages
  • upgrade to react 18
  • yarn install -D @types/react @types/react-dom, which automatically uses v18 types now. (or npm install --save-dev ...)

I'm sure there's a way that doesn't require you to uninstall first via yarn upgrade, but that didn't work for me for some reason.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ken Rimple
Solution 2 Brent Traut
Solution 3 Yaser AZ
Solution 4 Ty Hitzeman