Converting a React Codebase to Typescript. Part 1: Getting it to compile

Flatris

We’ll be porting Flatris. Flatris is a tetris implementation in React and Redux, with full offline capabillities and autosave.

Plugging in the Typescript compiler

Flatris uses Create React App(CRA), which makes life easy for us. CRA works by having an internal module called “react-scripts” that deal with most of the build configuration. Luckily someone’s made react-scripts-ts (RST), which is the typescript equivalent.

npm install -g create-react-app # Or use yarn create-react-app flatris --scripts-version=react-scripts-ts
tsconfig.json
tsconfig.test.json
tslint.json
Bugfixing is often like this, but with more tears.

Error Whack-A-Mole

Can’t find index.tsx

Error: Can’t find index.tsx

React has no default export

Error: (1,8): Module flatris/node_modules/@types/react/index"' has no default export.
import React from "react";
import React from ‘react’
import * as React from ‘react’

Could not find declaration file for module

Error: (3,26): Could not find a declaration file for module ‘react-redux’. ’flatris/node_modules/react-redux/lib/index.js’ implicitly has an ‘any’ type.Try `npm install @types/react-redux` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-redux';`
"noImplicitAny": true,
"strictNullChecks": true
"defaultSeverity": "warning",

Type errors

Error: /flatris/src/index.tsx (24,76): Property 'game' does not exist on type '{}'.
localStorage.setItem('flatrisState', JSON.stringify(store.getState().game);
localStorage.setItem('flatrisState', JSON.stringify((store.getState() as any).game));

React components contain invalid characters

Edit 24/05 — a pull request has been merged into react-scripts-ts. The below part should no longer be relevant.

Error: InvalidCharacterError: String contains an invalid character
Warning: </static/media/App.e52f775a.jsx /> is using uppercase HTML. Always use lowercase HTML tags in React.
Dante never got to write about it, but the tenth circle of hell primarily consists of monkey-patching minified javascript.
"prepare": "patch-package"
yarn add --dev patch-package postinstall-prepare
{
test: /\.(ts|tsx)$/,
include: paths.appSrc,
use: [
{
loader: require.resolve('ts-loader'),
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true,
},
},
],
},
test: /\.(ts|tsx|js|jsx)$/,
patch-package react-scripts-ts
Hallelujah! No more errors!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Gustav Wengel

Gustav Wengel

Software Developer at SCADA Minds