Surviving the TypeScript Ecosystem — Part 6: Branding and Type-Tagging
--
Source on Github: TypeScript Demo
A quick note before we get into it: All of the examples in this post use TypeScript v2.9.1. If you see different behavior check your version. I will try to update examples from time-to-time with TypeScript updates.
Introduction
Previously in this series I wrote a post about how TypeScript uses a structural type system (Interfaces and Structural Typing). In this post we are going to look at how to add pseudo nominal typing to our TypeScript files. That is we are going to look at how to make the names of types important in determining type equivalence.
Why is this Important?
This will become more clear when we look at an example, but for now let’s just say you have two types (they could be objects, strings, numbers) that are structurally equivalent but are used for very different things in your code. Numbers are common for this. A number could be a user id, a phone number, tracking number… many things that are important, maybe even private and used for security. To a structural type system there is no way to say that this function should only work on user ids and not be allowed to received other numbers that could result it getting data for the wrong user. We can’t stop people from committing errors, or being completely incompetent, it will happen. However, we can make it harder. We can make it so a user id is not equivalent to every other number in our system.
Getting Started
While this post can stand alone, it is one post in a series. If you would like to start from the beginning check out: Writing Type-Safe(ish) JavaScript Code. The most significant thing there is seeing how I have my project set up so you can follow along with the code examples.
Branding and Type-Tagging by Example
$ git checkout branding
A common example of numbers that can be nominally typed is currency. You could just use a number to represent currency, but if you are dealing with multiple currencies, say US dollars and Euros this can get confusing. You don’t want to pass a number representing US dollars to a function…