The release of TypeSciprt 1.6 includes support for React components. I decided to give it a whirl and see what TypeScript has to offer.
The end result is a port of the Redux TodoMVC example to TypeScript. (See my repo on GitHub)
I will cover the following topics:
- What are types, and why we need them?
- How TypeScript can help us develop React applications.
- Additional considerations when choosing TypeScript and React.
typingsas opposed to
tsd, which is the direction the community has adopted.
Types are good for you
If you have experience in Java (or in a similar statically typed language), you may be immediately turned off by types. The first thing to note is that a type in TypeScript is not a class. A more mathematical definition of a type is that a type is a name given to the set of inputs and outputs of a given function. That is, a type describes the interface of a function. This is the way I think about types.
Say I have a function defined as follows:
add function above says that it takes in two parameters
b both of type
number, then outputs
number. Thus, if I write any of the following statements, I will get a compile error.
If you are using an IDE that supports TypeScript you will get editor hints as you are typing.
As seen above, types gives us two benefits.
- Catch errors early on during compile time, not runtime.
- Serves as documentation for functions. And in editors that support TypeScript, we get type hints as we code.
Expanding on point #2, the type hints are especially useful for options object, as seen in libraries like jQuery.
Say I have this function defined below.
As a user of
doSomething I might wonder what options I am allowed to pass in. With the
Options type defined
below, I will get hints in our editor as I code.
More on types
Before we move on to React examples, I want to expand on types a bit more.
As mentioned earlier, types in TypeScript are not classes. The following defines a
Todo type, but does not create a class.
id? syntax means that the
id property is optional (since a new
Todo may not have an ID yet).
Given the above definition, I can now do the following.
What is more interesting is that I can use the type to form an interface over a function that operate over
Again, you will see errors in editors that support TypeScript as you are typing.
You can even define types for functions.
Union types and type guards
The last thing I will show is union types. A variable of an union type can be assign any type within that union.
Notice that there are no interfaces or subclasses defined above for
numberOrString. Union types can be combined with type
guards to help manage branches within a function.
The above features are enough for us to jump into the TodoMVC application. If you want to learn more about TypeScript, I found the Handbook to be a useful resource.
TodoMVC in React, Redux, and TypeScript
By now you have seen some of the benefits of using a powerful type system. But how does this fit in with React?
With TypeScript 1.6, you can now write your React components in TSX files. The following is an example from my TodoMVC example.
Note: Since React does not provide TypeScript definitions,
we cannot use it without providing ambient module definitions (e.g.
In this case, I am using a tool called
to install the missing definitions.
You can view the
file to see all of the definitions I have installed.
Properties interface vs React.PropTypes
Properties interface differs from
React.PropTypes in that the latter will only give you errors during runtime. With
Properties interface we can get feedback immediately from the compiler.
Unfortunately, as of this writing Visual Studio Code (the editor I am using) does not seem to support TSX files yet. The above errors were from Webpack with ts-loader.
Types and Redux
In the TodoMVC example, I defined a
Todo type that is used throughout the application. It is used as the return
. The state of
Todo. And the
all take in
Todo as properties.
This ensures that as I am coding, my actions and reducers (stores) all work with the correct types.
I now benefit from all the type hints and errors when working with my actions and reducers.
Using union types as models
Let’s add an initializing state to the
todos reducer by introducing a
Model union type for it.
We’ll have to change our reducer’s state from type
Model, and add type guards to our
The type guard ensures that in the
state is of type
Todo, which is why the above code compiles.
Initializing, but used an interface instead. The downside of this approach is that you cannot use
state instanceof Initializingin the type guard since interfaces are not available for reflection during runtime. It's up to you how you want to implement your own types.
Rendering the initializing state
App component, I can use the same
Model and type check function to render an initializing state.
The alternative to this approach might be to change our state to the following type.
This trades in the union type for a boolean flag to let us know why
null. This makes
our state much harder to reason about when we add in more and more flags and metadata. From my experience with real-world
applications, doing this type of thing is hard to avoid without types.
This initialization example is a bit contrived, but I hope it shows the power behind the technique. I have a branch of that shows how the above code works in the TodoMVC app. Fair warning, it is not completely functional because I only did enough work to get a few examples.
In this post I offered a glimpse of how TypeScript can help you when writing a React application. Some benefits you will receive are:
- Type hints as you code (in editors that support TypeScript).
- Type errors during compile time, or as you code in supported editors.
- Guarantees against certain classes of errors when your application compiles successfully. (typos, wrong
- Union types to simplify application state.
Does this mean you should rewrite your React application in TypeScript right now? It’s up to you. There are downsides in choosing TypeScript.
- Your favourite editor may not support TypeScript. Best editors right now would be WebStorm or Visual Studio Code IMO.
As of this writing, Visual Studio Code does not support TSX files (at least from my observation).
(As Franck pointed out in the comments, you can point the
typescript.tsdkoption in your VSC
settings.jsonfile to the lib directory of your TypeScript install)
- You will need to invest in more tools (TSD, ts-loader for Webpack, etc.).
If you think the benefits outweigh the the costs, definitely give TypeScript a go!
- TodoMVC in React and Redux
- TypeScript Handbook
- TypeScript and JSX
- Redux (Flux-like framework)
- Hello World with TypeScript and JSX (This one helped me debug some errors)