Category Archives: TypeScript

Upgrading a React and TypeScript app from react-scripts-ts to Create React App v2.1

Recently, the React team updated Create React App with official support for TypeScript. Create React App makes it easy to create web apps with React by keeping the details of the build process out of your way. No need to configure Webpack, Babel, and other tools because Create React App offers very high quality defaults. It’s not a boilerplate, though. You don’t even need to see the build dependencies and scripts, unless you want to, and upgrading to new versions is super easy. TypeScript is a popular extension to JavaScript that adds compile-time type checking. The two combined, in my opinion, provides one of the best developer experiences you can get for modern frontend web development.

Previously, to use TypeScript with Create React App, you had to create your project with the custom react-scripts-ts, created by Will Monk. Starting in version 2.1 of Create React App, TypeScript works out of the box. I have several projects that were started with react-scripts-ts, and I recently decided to start upgrading them to Create React App v2.1. I thought I’d share the steps that I followed and my experiences with this process.

Create a new baseline app

To start, I decided to create a completely new app with Create React App. I figured that it would be a good idea to have a baseline app, where I could compare its files — like package.json and tsconfig.json — with the files from my existing projects. This new app would give me clues about what exactly I need to change to make the existing apps work properly with the new version of Create React App.

To create a new app, I ran the following command in my terminal:

npx create-react-app my-new-app --typescript

Update library dependencies

In the existing project that I was upgrading, some of my dependencies hadn’t been updated in a little while, so the next step I decided on was to update the react, react-dom, typescript dependencies, along with the type definitions, like @types/react, @types/react-dom, @types/node, and @types/jest. After updating the versions in package.json, I ran npm install to download them all.

I left react-scripts-ts untouched for now. The idea was to make sure that the existing project was using the exact same versions of the dependencies as the new baseline project, and it should still build properly with react-scripts-ts. It’s best to ensure that I wouldn’t run into any issues with new versions of React or TypeScript that might confuse me as a worked through any issues caused by the differences between react-scripts-ts and the official react-scripts.

I needed to make a couple of minor tweaks to so that the new version of the TypeScript compiler was happy, so it was a good thing that I took this extra step.

Switch from react-scripts-ts to react-scripts

Once all of my library dependencies matched and the project would still build with react-scripts-ts, it was time to switch to the official react-scripts. Inside package.json, I replaced the react-scripts-ts dependency with react-scripts. I copied the version number of react-scripts from my new baseline project. Then, I needed to update the npm scripts inside package.json to use react-scripts:

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"

I replaced react-scripts-ts with react-scripts in each of the npm scripts above. Then, inside the build script, I saw that my existing project included a --env=jsdom option, but the new baseline project did not. I removed this option so that they matched.

Update configuration files

Next, I compared tsconfig.json in both projects. I could see some major differences, like outputting ES Modules instead of CommonJS, and preserving JSX so that Babel could handle it instead of letting the TypeScript compiler do everything. I decided that I would simply copy the contents of tsconfig.json from the new baseline project to the existing project and then make a couple of small tweaks. I ended up setting the lib compiler option to ["es2015", "dom"] so that I could access some newer JS APIs, and I set the strict compiler option to false because I haven’t updated my project to use strict mode yet. Otherwise, I used Create React App’s defaults, which all seem to be working well.

Similarly, I compared package.json in the two projects. I had already updated the dependencies and npm scripts, so the differences at this point were very minor. I saw that the new baseline project included two new fields that were not in the existing project, eslintConfig and browserslist. These defaults (which configure eslint and Babel) provided by Create React App seemed fine, so I copied them over.

In theory, the migration process should be done at this point. If all goes well, you should be able to run npm start to launch the development server, or you can run npm run build to create a production build. For my project, I ran into a couple of issues that I needed to resolve, but nothing major.

Fix compiler errors

I use the react-loadable library to load parts of my app at runtime using code splitting. My imports in TypeScript originally looked like this:

import * as ReactLoadable from "react-loadable"

However, there seemed to be a problem with the following code:

let AdminHomeScreen = ReactLoadable({
  loader: () => import("./AdminHomeScreen"),
  loading: LoadingScreen

The TypeScript compiler gave me the following error:

Cannot invoke an expression whose type lacks a call signature. Type ‘{ default: Loadable; Map<Props, Exports extends { [key: string]: any; }>(options: OptionsWithMap<Props, Exports>): (ComponentClass<Props, any> & LoadableComponent) | (FunctionComponent<Props> & LoadableComponent); preloadAll(): Promise<…>; preloadReady(): Promise<…>; Capture: ComponentType<…>; }’ has no compatible call signatures.

For some reason, I could not call the ReactLoadable module as a function. It turned out that I needed to change the import to look like this instead:

import ReactLoadable from "react-loadable"

In order to call a module like a function, you need to import the module’s default export. I think this may have been related to switching from CommonJS modules to ES Modules in tsconfig.json.

After fixing this issue, I could successfully run npm start to launch the development server, and I could open my app in a web browser and use it! However, I discovered one last issue that I needed to fix.

Fix production build

While npm start worked for development, I got a strange error when I ran npm run build to create a production build of my React app.

throw err;

Error: Cannot find module ‘webpack/lib/RequestShortener’
at Function.Module._resolveFilename (module.js:548:15)
at Function.Module._load (module.js:475:25)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object. (C:\Users\josht\Development\karaoke-butler\karaoke\client\node_modules\terser-webpack-plugin\dist\index.js:19:25)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
npm ERR! errno 1
npm ERR! react-client@1.0.0 build: `react-scripts build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the react-client@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\josht\AppData\Roaming\npm-cache\_logs\2018-11-25T01_57_14_654Z-debug.log

Unfortunately, a quick Google search did not find anyone having the same issue with Create React App. However, I saw some folks using other frameworks, like Vue or Angular, were getting similar errors. Eventually, I found someone who discovered that it was some kind of conflict inside the notorious package-lock.json. Ever since npm started using this file, it’s been a terrible source of problems, in my experience.

Anyway, I deleted package-lock.json and the node_modules folder. Then, I ran npm install to install all of my dependencies from scratch. That did the trick because npm run build started working correctly.

I don’t really know why package-lock.json always seems to cause problems like this, but I find that deleting this file and the entire node_modules folder frequently fixes issues that I run into. I don’t know if I’m doing something wrong, or if it’s a bug in npm.

My project is upgraded

Updating dependencies in some of my web projects can be daunting sometimes. For some of them, I usually need to set a full day aside to fix everything. With that in mind, I was expecting to hit a few more snags in the process of upgrading from react-scripts-ts to the official version of Create React App. However, the changes required in my app were relatively minor. The process felt very smooth, and I’m happy that I’ll be able to easily update to new versions of Create React App in the future as the React team continues to innovate.

Migrating an Apache Flex app to React: Milestone 2

Back in January, I wrote a post about reaching the first milestone in the process of converting my app from Flash Player to plugin-free HTML & JavaScript. That first milestone involved converting a subset of the app (a non-editable view of a simulated circuit) so that I could embed interactive examples inside the help files for Once I got that finished, it was time to move on to the next, more ambitious, milestone. For the last ten months (roughly two hours a day, four to five days per week), I’ve been working on enabling nearly every feature of the full app. Last week, I replaced the online demo of that was previously using Adobe Flash Player with a fully JavaScript and HTML DOM powered version, built with React and TypeScript.

I thought I’d share some of my thoughts on the libraries, tools, and platform that I’ve immersed myself in throughout 2018, and how it compares to my long experience with Adobe’s Flash platform.


I’ve come to enjoy React quite a lot. Especially React combined with TypeScript. React uses JSX, an XML-like way to describe UI that is very similar to MXML in Flex. However, JSX flips things around compared to MXML. Instead of script being embedded in XML, XML is embedded in the script. This makes it really easy to conditionally render parts of the view based on state, or to even loop through arrays to repeat multiple instances of the same type of component. As you can imagine, JSX’s flexibility has the potential to lead to some pretty gnarly spaghetti code. However, with care, JSX feels to me like a superior paradigm to MXML.

React’s ecosystem is very active and full of high quality, custom components and libraries. Reach Router, react-beautiful-dnd, and react-loadable are just three wonderful examples of open source packages that are worth checking out. The only thing that I’ve struggled with is finding the “perfect” UI control library that has a decent number of core components, works on both desktop and mobile, and also offers a robust styling system.

I’m using Semantic UI for the UI, which is generally pretty serviceable. However, like many React UI control libraries that I evaluated, there are a ton of components that I don’t need right now (which isn’t a bad thing), but some more basic components are surprisingly missing (which is kind of weird). For instance, Semantic UI doesn’t offer a slider/range component. In fact, the slider/range is one of the most commonly missing components in various other React UI control libraries that I also evaluated, which has me baffled because it’s such a common piece of UI. In the end, I used the regular HTML <input type="range"> as a fallback, but it feels out of place and requires some hacky styling.


As you may know, the most popular architecture framework for React is Redux, and that’s what I’m using for It provides the same kind of structure/organization to a project as many of the MVC frameworks that Flex developers probably encountered over the years — like Robotlegs, Swiz, PureMVC, Cairngorm, and others. Interestingly, it also heavily leans into functional programming concepts, including expecting the data it stores to be immutable.

I’m not a huge fan of Redux, to be honest. It’s better than no framework at all for a big app like, but I hope that something better comes along eventually.  I understand Redux’s benefits, but from a developer experience perspective, I just don’t like the way it feels. Some people claim that it has a lot of boilerplate, but I didn’t feel like that was something that bothered me. Sure, there’s probably some room to streamline things a little, but I think I’m more turned off by reducer concept and immutability requirements. I understand that this type of architecture is a big part of functional programming, but it feels “off” in a UI development environment where things are often more naturally represented with an object-oriented paradigm.

Recently, I saw some people talking about Immer, a library that provides immutability with an API that acts more like mutable data. That’s really interesting to me, and I think that it might improve the Redux experience to be more like what I prefer. Hopefully, I can find some time in the future to check out Immer and give it a test drive.


After years with ActionScript, TypeScript offers many of the same familiar improvements over JavaScript. It also provides a ton of really useful new features that ActionScript doesn’t provide (and won’t be getting in the future). Here are some of my favorites:

More flexible interfaces. You don’t need to create a class to have an object implement an interface in TypeScript. If you have an IPoint interface that has x and y properties, you could set a variable’s type and assign a value like this:

let p: IPoint = { x: 10, y: 15 };

Type inference. A smarter compiler that can figure out a variable’s type from context is probably the biggest advantage of TypeScript over ActionScript, in my opinion. It saves an incredible amount of typing. In the code example below, the compiler is smart enough to figure out that n should be a number and s is a string:

let n = 123;
let s = "Hello";

Proper generics. In ActionScript, we only had the Vector type. In TypeScript, you get the full power of creating your own types that use generics. That means less casting required and better chances that the compiler will catch a mistake.

let map = new Map<string,MyType>();

Arrow functions. Being able to define a local function where this matches the scope of the surrounding method reduces so many headaches. Plus, the shorthand syntax of arrow functions is super slick.

myArray.forEach( item => console.log(item) );

The let keyword. Using var in JavaScript and ActionScript creates a variable in the scope of the local function. Other languages usually create variables in the scope of the nearest block. So, if you created a variable inside the body of an if() statement or a for() loop, you wouldn’t be able to access it outside that block. Using let makes JavaScript and TypeScript variables more like those other languages:

    let value = false;
value = true; //error because value is not in this scope

Performance isn’t your typical form-based app, and it can potentially display hundreds (or thousands) of objects in the editing surface at the same time. To keep performance high, I needed to customize the update behavior for some components to ensure that React was performing well and not rendering too frequently. This isn’t anything that’s wrong with React. In fact, there are established best practices for my situation, which is a great indicator of maturity.

In some places, I could easily switch to using PureComponent, and here and there, I created some custom shouldComponentUpdate() methods for even more control over rendering. I made heavy use of the React Dev Tools to ensure that my components weren’t rendering too often, and ultimately, all of my work paid off. I haven’t even had the chance to try out the new React Profiler yet, which I expect will improve performance even more.

Many parts of running on top of React and JavaScript are much faster than the old Flex and Flash Player version of the same app. Part of that is probably thanks to the ground-up rewrite. Anytime you start from scratch, you get to drop some of the baggage that you had before, and you can make better architecture choices from the beginning. However, React’s virtual DOM and decreased reliance on events/observers/binding is probably a non-trivial part of it too.

There’s also the fact that JavaScript virtual machines have kept on improving over the last several years, while the ActionScript virtual machine hasn’t evolved since Adobe stopped investing heavily in the platform several years back. There was a time when types in ActionScript gave it a huge advantage. Now, JavaScript VMs do things like create their own internal shadow types to use with dynamic objects behind the scenes, which basically makes JavaScript as fast as ActionScript once interpreted code is converted to bytecode. Combine that with a ton of other JS optimizations, and while I’m sure that Flash Player is still faster here and there, it doesn’t have the major advantage it used to have 10 or more years ago.

One place where switching to JavaScript shines is being able to take advantage of code-splitting. This allows to load only the parts of the code that it actually needs, and load the rest on demand. I’m able to show UI to the user faster than before (so that they can start using the app sooner, instead of waiting for everything to complete loading), and I can ensure that their bandwidth usage is minimized. Flex had the concept of modules, and any SWF can load other SWFs, of course. Additionally, SWFs support preloading the first frame to show some kind of loading screen to keep the user distracted. However, setting up code splitting in JavaScript is significantly easier and more powerful, in my opinion. It happens automatically any time that I reference a module with import(). It’s great! If Flash Player were still a competitive platform for deploying to the web today, I’m sure that Flex would have a smarter automatic module system by now, but as a fading platform, it’s (not unexpectedly) falling behind on things like this.

Limitations of the web platform

Even with all of the great advancements for frontend web developers over the last several years, there are still places where Flash Player still does things better. Here are a couple of places where I ran into trouble or where things felt half-baked.

There’s no JS equivalent to localToGlobal() and globalToLocal() to convert points between different coordinate spaces. Well, that’s not completely true. SVG exposes an API for converting points between the SVG coordinate space and the global coordinate space of the surrounding page, and I guess that’s probably what I’m supposed to use. I found that it’s a little clunky, but I made it work… but only successfully in Chrome and Edge. I discovered that once you use CSS transforms on some elements, such as scaling or rotation, converting points between different coordinate spaces did not work correctly in both Firefox and Safari. This is absolutely necessary in, since the editing surface can be zoomed in and out, so I had to write my own conversion function to handle scaling when trying to position objects in two different coordinate spaces. It was not ideal. I’m actually surprised that this functionality is broken in two major browsers. I’ve made heavy use of localToGlobal() and globalToLocal() in Flash for well over a decade, and I know they’re commonly used in a ton of ActionScript projects, so I would have expected them to be nearly as important to JS developers.

I find it frustrating that there’s no global event dispatching API in JS that anyone can use with their own custom types and objects. The HTML DOM can dispatch events, and other types like XMLHttpRequest can too. This feels like an odd omission. Sure, there are third party libraries, but none of them are completely compatible, so you could end up with a dozen different implementations of events in one app, if you aren’t careful. The EventDispatcher type (and IEventDispatcher interface) in ActionScript powers the Flash display list, networking APIs, and basically everything that’s built-in, and it can also be used by custom ActionScript classes. This helps everything feel more cohesive in the Flash world, and it limits the amount of duplicated work required by developers in the ecosystem. At least the JS world seems to be trying to standardize on Promises for many things now where events were used in the past. However, adoption of promises has been in progress for years, and we’re not anywhere near using them for everything yet. I don’t see this situation improving any time soon, which is unfortunate.

On to the next milestone!

Whew! That was quite a lot for me to bring together. So, what’s next? Well, I still need to migrate the desktop version of to the new codebase. I will probably use Electron when I start working on that. However, I think that I will save that for a bit further in the future because I recently decided that it was time to start thinking about finally bringing to mobile.

Milestone 3 will be updating the online demo to provide a more mobile-friendly UI on Android tablets and iPad. Right now, mobile users get the desktop version with a few very minor tweaks. I knew that migrating to JS/HTML and adding in a mobile UI would be too much to handle all in one step, so I decided to keep it simple for the previous milestone. Finally, in the last couple of weeks, I’ve started working on the mobile UI, and things are moving forward smoothly and rapidly. Soon after I update the online demo for mobile, I’d like to expand the codebase into a full-fledged mobile app that I’ll release on the iOS App Store and Google Play. These new sources of revenue will hopefully enable me to have more time to work on updates to in the future! I plan to look into using Capacitor to build the mobile app.

react-loadable and TypeScript error: Property ‘render’ is missing in type ‘{ loader: () => Promise

The react-loadable library provides an excellent way to load React components on demand while displaying a temporary view until they finish loading (such as a spinner animation). Recently, I tried using react-loadable with TypeScript, and the compiler reported a strange and unexpected error. Here’s the journey I took figure out what was wrong, and how I fixed it.

You can see that my code below is very simple, but I was getting an error, for some reason:

import * as React from "react";
import * as Loadable from "react-loadable";
import MyLoadingComponent from "./MyLoadingComponent";

const LoadableMyComponent = Loadable(
	loader: () => import("./MyComponent"),
	loading: MyLoadingComponent

The full compiler error appears next (with a modified file path to make it more readable):

Argument of type '{ loader: () => Promise<typeof "/path/to/MyComponent">' is not assignable to parameter of type 'Options<any, typeof "/path/to/MyComponent">'.
  Type '{ loader: () => Promise<typeof "/path/to/MyComponent">' is not assignable to type 'OptionsWithRender<any, typeof "/path/to/MyComponent">'.
    Property 'render' is missing in type '{ loader: () => Promise<typeof "/path/to/MyComponent">'.

In my editor, the error begins at the opening curly brace { and ends at the closing curly brace }, so it’s clear that there’s something wrong with the options object that I’m passing in. However, it was not immediately obvious to me why the TypeScript compiler didn’t like my object.

The error says that a render property is missing. My first thought was that I was missing a render() method in a component somewhere. However, both MyComponent and MyLoadingComponent are React components with proper render() methods defined.

The code for MyComponent.tsx appears below:

import * as React from "react";

export default class MyComponent extends React.Component<any>
		return <div>MyComponent has loaded</div>

And here’s the code for MyLoadingComponent.tsx:

import * as React from "react";

export default class MyLoadingComponent extends React.Component<any>
		return <div>Loading...</div>;

As you can see, render() is not missing in my components. So where exactly should a property named render be defined?

After reading through the react-loadable documentation, I figured out that the options object can be one of a few different variations, and one of them requires a render property. The TypeScript compiler thinks I’m trying to use the variation where this property is required…

…but I’m not.

According to the following comment from the type definitions, I need to meet the following requirements to make the render property optional:

If you do not want to provide a render function, ensure that your function is returning a promise for a React.ComponentType or is the result of import()ing a module that has a component as its `default` export.

You can see that the function that I pass to the loader property should work. I’m loading a module containing MyComponent as the default export, and it extends React.Component.

loader: () => import("./MyComponent")

After some trial and error, I determined the real problem. The React component that I pass to the other option (loading) isn’t accepted because I typed its “props” as any:

class MyLoadingComponent extends React.Component<any>

According to the type definitions for react-loadable, I should use ReactComponent.<Loadable.LoadingComponentProps> instead. I would have expected the TypeScript compiler to figure out that Loadable.LoadingComponentProps can be assigned to any, but I guess not.

Anyway, here’s how I should have defined MyLoadingComponent instead:

import * as React from "react";
import * as Loadable from "react-loadable";

export default class MyLoadingComponent extends React.Component<Loadable.LoadingComponentProps>
		return <div>Loading...</div>;

It took me quite some time to figure out what exactly was wrong with my code. The TypeScript compiler was fixated on that render property, which led me down the wrong path. I wish the compiler would have realized that my React.Component was using type any for its props instead of the Loadable.LoadingComponentProps. I wonder if there’s a better way to define these options in the type definitions so that the wrong type for props would have taken precedence over the missing (but not really) render property?