TypeScript's enum + JavaScript's "in" = 👍
Tags: typescript, javascript, webdev
Published: 2020-11-08 22:37:49

---
title: TypeScript's enum + JavaScript's "in" = 👍
published: true
description: Using TypeScript's enum and JavaScripts `in` operator to tidy up messy logic.
tags: typescript,javascript,webdev,
cover_image: https://images.unsplash.com/photo-1575440114389-70195f97d9b0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80
---

At cinch, I work on the inventory team and we manage all of the vehicle inventory, tracking the status, location and all kinds of other data for thousands of cars. We have an event driven architecture which means parts of our code respond to certain events which we subscribe to. We have a state machine/model which contains a LOT of logic to determine moving cars from one status to another. I came up with the following pattern when I noticed some hefty `if` conditions in the codebase.

In this example I'm going to use robots as the subject as I write code to do with vehicles every day! 🚗

Let's imagine we want a function which disposes of a robot but we can only dispose of the robot if it's status is `faulty` or `damaged`. Below we setup our enum `RobotStatus` to list our possible robot status and a `Robot` interface to build the shape of our robot.

```typescript 
enum RobotStatus {
    ready,
    damaged,
    faulty
}

interface Robot {
    name: string
    status: RobotStatus
}

function disposeRobot(robot: Robot): void {
    if (robot.status === RobotStatus.damaged || 
        robot.status === RobotStatus.faulty
    ) {
        console.log('Disposing of robot...')
    }
    
    console.log('Robot in incorrect state to dispose...')
}
```
This is fine for now. But imagine if we had to start adding more checks for other status. Let's add some more for `discontinued`, `dead`, `old`, `rusty`, and `dangerous`.

```typescript
enum RobotStatus {
    ready,
    damaged,
    faulty,
    discontinued,
    dead,
    old,
    rusty,
    dangerous
}

interface Robot {
    name: string
    status: RobotStatus
}

function disposeRobot(robot: Robot): void {
    if (robot.status === RobotStatus.damaged || 
        robot.status === RobotStatus.faulty ||
        robot.status === RobotStatus.discontinued ||
        robot.status === RobotStatus.dead ||
        robot.status === RobotStatus.old ||
        robot.status === RobotStatus.rusty ||
        robot.status === RobotStatus.dangerous ||
    ) {
        console.log('Disposing of robot...')
    }
    
    console.log('Robot in incorrect state to dispose...')
}
```
Now that `if` block is getting chunky and it stinks 👃.
Let's create an `enum` containing our allowed disposable statuses.

```typescript
enum DisposableStatus {
    damaged,
    faulty,
    discontinued,
    dead,
    old,
    rusty,
    dangerous
}
```

JavaScript has an `in` operator which will return true if the specified property exists in the specified object. 

```shell
prop in object
```

This can clean up our `if` block from above. Let's use it...

```typescript
function disposeRobot(robot: Robot): void {
    if (robot.status in DisposableStatus) {
        console.log('Disposing of robot...')
    }
    
    console.log('Robot in incorrect state to dispose...')
}
```
TypeScript will compile the enum into a regular JavaScript object and these properties will exist at runtime 👍.
This is much more readable and easier to digest for your future self and other developers.