Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Created November 6, 2022 05:50
Show Gist options
  • Save CMCDragonkai/dba1cb48f4c864fab22c2851011bef7e to your computer and use it in GitHub Desktop.
Save CMCDragonkai/dba1cb48f4c864fab22c2851011bef7e to your computer and use it in GitHub Desktop.
Tagged Unions in TypeScript #typescript #adt

There are number of ways of creating tagged unions.

type X = { type: A, prop: number } | { type: B, prop: string };

type Y = { type: A, data: { prop: number } } | { type: B, data: { prop: string } };

type Z = ['A', { prop: number }] | ['B', { prop: string }];

Consider that generally in tagged unions, the tag is not part of the type being unioned.

This is because the tag is only necessary for disambiguation.

If you have disambiguated, then the tag is unnecessary.

In the examples above, only Y and Z well formed, because they can also be recursive.

In X, the tagged union can conflict with the type property of the unioned types.

I've started to prefer Z because it is has less syntax overhead, and it more closely matches how Haskell does it.

In fact in haskell, the Z lends itself easily to pattern matching, where one can pattern match the first element, then use the underlying data.

In TS, we have to do something like this:

const [type, data] = z;
switch (type) {
  case 'A':
    const { prop } = data;
    break;
  case 'B':
    const { prop } = data;
    break;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment