Union Types — A better way to describe your data
In my brief foray into Elm programming, one feature that I grew very fond of was Union Types. Let’s take a look at these and examine how we can use them to our advantage with Elm and TypeScript.
Many languages have trouble expressing data with weird shapes. They give you a small set of built-in types, and you have to represent everything with them. So you often find yourself using
nullor booleans or strings to encode details in a way that is quite error prone.
Elm’s union types let you represent complex data much more naturally. — Evan Czaplicki (Author of Elm-lang)
People often note that Redux was very much inspired by Elm. In both Redux and Elm, you represent the way data flows and changes in your application through an interface that very closely mirrors Union Types and how Elm uses them. Let’s take a look at some code to demonstrate this.
When I first learned Elm and realized the similarities between Redux and the Elm Architecture, I was like…
Where were we? Ah yes, Union types. As you can see above, I am making use of a Union Type in the
This is a totally different story in Elm. The compiler aids you along the way with awesomely helpful features. In fact, you cannot compile your Elm app if you misspell a type or a constant. This is really where the power of Union Types comes in
When you call the
update function, you literally have to send it one and only one of the
Msg types and if you try to send it something else, it will not compile. If you forget to handle one of the cases, you will get a friendly message from the Elm compiler saying that you forgot to handle all of your cases without a default case.
What this means is that you can catch all of your bugs at compile time rather then when the code ships to your client. This means that you spend a whole lot less time chasing down run-time errors and writing test-cases to protect against this. On top of that, the Union Types let us describe our data and how to manipulate that data in an incredibly declarative and descriptive way.
Building and documenting UI Component Libraries with Static Types
React pioneered the concept of building self-contained reusable UI component libraries. Over the last few years, we have seen some truly amazing component libraries come out. Grommet UX, Material UI, Blueprint and Ant.Design, to name a few. It has always been a goal of mine to work on a library and thus have been a contributor to the Grommet project. Seeing how one of the best of these libraries was built has given me some perspective on what works and what doesn’t.
In building a React / TypeScript open source boilerplate, I found that my ability to create a reusable UI components as part of my normal workflow was increased. Not only that, but I also found that the time spent documenting and testing the project was far less than normal. This is due to the fact that the TypeScript compiler, much like the Elm compiler, can give you helpful advice and allow you to embed metadata that describes your intentions within your code for the compiler to use. It allows you to document your code as you write it and with intelligent tooling will even generate the documentation for you.
If I were to start building a brand new UI Kit tomorrow, I would definitely use TypeScript for these reasons.