{
  "$type": "site.standard.document",
  "canonicalUrl": "https://johnnyreilly.com/posts/react-18-and-typescript",
  "description": "Upgrade React to `@next` and add new type definitions to use React 18 alpha with TypeScript. Use `ReactDOM.createRoot` API.",
  "path": "/posts/react-18-and-typescript",
  "publishedAt": "2021-06-30T00:00:00.000Z",
  "site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
  "tags": [
    "react",
    "typescript"
  ],
  "textContent": "React 18 alpha has been released; but can we use it with TypeScript? The answer is \"yes\", but you need to do a couple of things to make that happen. This post will show you what to do.\n\n\n\nCreating a React App with TypeScript\n\nLet's create ourselves a vanilla React TypeScript app with Create React App:\n\nNow let's upgrade the version of React to @next:\n\nWhich will leave you with entries in the package.json which use React 18. It will likely look something like this:\n\nIf we run yarn start we'll find ourselves running a React 18 app. Exciting!\n\nUsing the new APIs\n\nSo let's try using ReactDOM.createRoot API. It's this API that opts our application into using new features of React 18. We'll open up index.tsx and make this change:\n\nIf we were running JavaScript alone, this would work. However, because we're using TypeScript as well, we're now confronted with an error:\n\n> Property 'createRoot' does not exist on type 'typeof import(\"/code/my-app/node_modules/@types/react-dom/index\")'. TS2339\n\nThis is the TypeScript compiler complaining that it doesn't know anything about ReactDOM.createRoot. This is because the type definitions that are currently in place in our application don't have that API defined.\n\nLet's upgrade our type definitions:\n\nWe might reasonably hope that everything should work now. Alas it does not. The same error is presenting. TypeScript is not happy.\n\nTelling TypeScript about the new APIs\n\nIf we take a look at the PR that added support for the APIs, we'll find some tips. If you look at one of the next.d.ts you'll find this info, courtesy of Sebastian Silbermann:\n\nts\n  import {} from 'react/next'\n  ts\n  /// <reference types=\"react/next\" />\n  \n\nLet's try the first item on the list. We'll edit our tsconfig.json and add a new entry to the \"compilerOptions\" section:\n\nIf we restart our build with yarn start we're now presented with a _different_ error:\n\n> Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Document | DocumentFragment | Comment'. Type 'null' is not assignable to type 'Element | Document | DocumentFragment | Comment'. TS2345\n\nNow this is actually nothing to do with issues with our new React type definitions. They are fine. This is TypeScript saying \"it's not guaranteed that document.getElementById('root') returns something that is not null... since we're in strictNullChecks mode you need to be sure root is not null\".\n\nWe'll deal with that by testing we do have an element in play before invoking ReactDOM.createRoot`:\n\nNow that change is made, we have a working React 18 application, using TypeScript. Enjoy!\n\nThis post was originally published on LogRocket.\n\n<head>\n    <link rel=\"canonical\" href=\"https://blog.logrocket.com/how-to-use-typescript-with-react-18-alpha/\" />\n</head>",
  "title": "React 18 and TypeScript"
}