---
Title: Sum Type Constructors in TypeScript
Subtitle: Or, making TypeScript into a terrible ML because I canât use Elm in my day job.
Category: Tech
Tags: [elm, typescript, programming languages]
Date: 2018-05-31 07:00
Summary: >
You can build the same kind of sophisticated discriminated union types in TypeScript as you'd get in Elm or Fâ¯. Kind of. With a lot of work. (Hereâs how.)
---
A pretty common pattern I've seen is to have three basic states for some kind of HTTP request: *loading*, *failure*, and *success*. Since each of these has its own associated date, it's a really good fit for a discriminated union or sum type. In a language like Elm (or F^â¯^ or Haskell or PureScript orâ¦) you'd write that basically like this:
```elm
module Fetch exposing (State)
type alias HTTPStatusCode = Int
type alias ErrorData = { code: HTTPStatusCode, reason: String }
type State a
= Loading
| Failure ErrorData
| Success a
```
Because I find that pattern extremely helpful, I've at times gone out of my way to replicate it in TypeScript. And what you get is⦠verbose. It's a necessary evil, given what TypeScript is doing (layering on top of JavaScript), and so much so that I wouldn't actually recommend this unless you're already doing this kind of programming a lot and find it pretty natural. If you are, though, here's how you get the equivalent of those four lines of Elm in TypeScript:
```typescript
type HttpStatusCode = number;
export enum Type { Loading, Failure, Success }
export class Loading {
readonly type: Type.Loading = Type.Loading;
static new() {
return new Loading();
}
}
type ErrorData = { code: HttpStatusCode, reason: string };
export class Failure {
readonly type: Type.Failure = Type.Failure;
constructor(readonly value: ErrorData) {}
static new(value: ErrorData) {
return new Failure(value);
}
}
export class Success