Skip to content

Instantly share code, notes, and snippets.

@ryuheechul
Last active October 25, 2019 08:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryuheechul/b02c5cfb2beaf3bd21bce057d7b3c431 to your computer and use it in GitHub Desktop.
Save ryuheechul/b02c5cfb2beaf3bd21bce057d7b3c431 to your computer and use it in GitHub Desktop.
My approach to deal with pattern matching types in Typescript
// Type enum (meta type)
enum Type {
Animal,
Digit
}
// types
enum Animal {
Cat,
Dog
}
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type AorD =
| { type: Type.Animal; val: Animal }
| { type: Type.Digit; val: Digit };
// helpers
function animal(a: Animal): AorD {
return { type: Type.Animal, val: a };
}
function digit(d: Digit): AorD {
return { type: Type.Digit, val: d };
}
// branching without switch
function handle(u: AorD) {
return {
Animal: (v: Animal) => handleAnimal(v),
Digit: (v: Digit) => handleDigit(v)
}[Type[u.type]](u.val);
}
/* above is clenaer looking than handle2 below
function handle2(u: AorD) {
switch (u.type) {
case Type.Animal: {
handleAnimal(u.val);
break;
}
case Type.Digit: {
handleDigit(u.val);
break;
}
}
}
*/
function handleAnimal(a: Animal) {
console.log(`this is an Animal: ${Animal[a]}`);
}
function handleDigit(d: Digit) {
console.log(`this is a Digit: ${d}`);
}
export function test() {
const x: AorD = animal(Animal.Cat); // => { type: Type.Animal, val: Animal.Cat };
const y: AorD = digit(3); // => { type: Type.Digit, val: 3 };
handle(x);
handle(y);
}
test();
@ryuheechul
Copy link
Author

As of today, the Typescript way of pattern matching is something that I wanted to avoid using because of inevitably using strings and switches.

  • I like Elixir and ReasonML's approach way better.
  • but sometimes [un]fortunately I have to use Typescript not ReasonML..
  • After I searched online to deal with this situation I wasn't satisfied with anything yet, so just played around and found somewhat satisfactory style of code which is uploaded here in this gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment