净化

Bridging the Gap Between Elm and JavaScript with TypeScript

净化 · 2017-11-03推荐 · 867阅读 CET/4 169 CET/6 10 原文链接

Bridging the Gap Between Elm and JavaScript with TypeScript

Recently, I have gone through a few language transitions: from JavaScript, briefly to Elm, finally landing on TypeScript. I wrote an article about this experience detailing why I finally chose TypeScript as my Front End language of choice. In this article, I would like to take a deeper dive into some of the features that I enjoy most about TypeScript

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.

Union Types, also known as tagged unions and Algebraic Data Types (ADTs) give you, the programmer, the ability to describe your data with far more precision than what is possible when only using JavaScript’s built in data-types.

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 null or 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.

Redux Reducer Example

The core abstraction in Redux is the reducer function. The reducer function acts upon the store, a representation of all of the data in your app, letting the developer tightly control state mutations in their apps. The data in a redux app must be treated as immutable and the only way that you can ever alter that data is to send an action to a reducer function which will look at the type of that action and return the next state. Coupled with Immutable JS, JavaScript has nearly all the capabilities of the Elm Architecture. The one missing piece is static types, especially Union Types. Below, I have rewritten a few of the cases from the above reducer function to demonstrate the similarities between Elm and Redux.

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 Msg type. The keyword here being type. When you are working with JavaScript and Redux, it is up to you to ensure that you write this reducer correctly. You must declare your action type constants and ensure they are spelled correctly and you also need to make sure not to mutate state within a reducer.

You write copious amounts of unit tests to ensure that you are handling all of your cases and are in fact returning what you think you are from your action creators / reducers. As your project evolves, things start to fall apart. It gets to be a struggle to keep all of your tests in sync with the changes you are making during your refactoring. Redux means well, but since JavaScript on its own does not have static typing, we get absolutely no help from the compiler when we write / refactor our code.

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.

Now, as I discussed in my previous article, as much as I love Elm I really have to keep writing JavaScript for the time being. TypeScript helps me to fill this void and first-class support for union types is one of the primary reasons. Let’s take a look at how you can use Union Types with Redux via TypeScript.

Does anyone remember this movie?

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.

Summary

Static typing is a feature that has long been missing from JavaScript. We are very fortunate to now have several choices that allow us to harness the powers of static typing while writing JavaScript. Whether you are coming from a Functional Programming background, or not, types can help you to write self-documenting code and they can help you to shape your data in ways that just aren’t possible without static typing.

My hope in writing this article is to show a few of the features that make me want to write typed JavaScript. If you enjoyed this article, please follow me and share it with your friends. Until next time!

相关文章