Transforming TypeScript Enums into Object Arrays
Tags: javascript, typescript, programming, node
Published: 2024-01-20 14:41:03

Typescript enums are of three types:
- **Numeric enum:**

    All enum members have numeric values.
- **String enum:**
  All enum members have string values.
- **Heterogeneous enum:**
  Enum members are mixed but its essential for numeric members to follow a valid numeric value order.

In TypeScript, enums are compiled into JavaScript objects ([here](https://www.typescriptlang.org/docs/handbook/enums.html#enums-at-runtime)). As a result, native object methods `Object.values()` and `Object.keys()`can be used at runtime to construct an object array from an enum. However, please note that the process may differ for each enum type.

### String enum
Its the most straight-forward enum type to constract arrays from. Utilize the `Object.values()` or `Object.keys()` method, depending on your specific requirements.
``` typescript
enum Scope {
    CREATE = "create",
    UPDATE = "edit",
    DELETE = "delete"
}

let Scopes = Object.values(Scope) as string[];
console.log(Scopes) // ["create", "edit", "delete"]

Scopes = Object.keys(Scope) as string[];
console.log(Scopes) // ["CREATE", "UPDATE", "DELETE"]
```
### Numeric enum
As enums are compiled to objects, accessing the value of an enum member using its key is standard. However, with numeric enums, the reverse is also possible – you can access the enum member key/name using its value. This behavior is referred to as **_Reverse-Mapping_**. [Read more](https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings)

In essence, keys become values, and values become keys :). Consequently, the output array of both `Object.values()` and `Object.keys()` methods will have twice the number of elements compared to the original enum.

You have the flexibility to trim or transform the results according to your specific requirements. 👇

``` typescript
// Numeric enum starting from 2.
enum Scope {
    CREATE = 2,
    UPDATE,
    DELETE
}

let Scopes = Object.values(Scope) as string[];
console.log(Scopes) // ["CREATE", "UPDATE", "DELETE", 2, 3, 4] 

Scopes = Scopes.splice(0, (Scopes.length/2)) as string[]
console.log(Scopes) // ["CREATE", "UPDATE", "DELETE"]

Scopes = Object.keys(Scope) as string[];
console.log(Scopes) // ["2", "3", "4", "CREATE", "UPDATE", "DELETE"]

Scopes = Scopes.splice(0, (Scopes.length/2)) as string[]
console.log(Scopes) // ["2", "3", "4"]
```
### Heterogeneous enum
> There is no Reverse-Mapping available for string enums or string enum members in case of Heterogeneous enums.  

Output of `Object.keys()` and `Object.values()` depends on the number of string and numeric members present in the enum.
``` typescript
// Heterogeneous enum with one string and three numeric members
enum Scope {
    CREATE,
    UPDATE = "edit",
    DELETE = 4,
    GET
}

let Scopes = Object.values(Scope) as string[];
console.log(Scopes) // ["CREATE", "DELETE", "GET", 0, "edit", 4, 5]

Scopes = Scopes.filter(scp => typeof scp === 'string' ) as string[]
console.log(Scopes) // ["CREATE", "DELETE", "GET", "edit"]

Scopes = Object.keys(Scope) as string[];
console.log(Scopes) // ["0", "4", "5", "CREATE", "UPDATE", "DELETE", "GET"]

Scopes = Scopes.filter(scp => Number.isInteger(Number(scp)) ) as string[]
console.log(Scopes) // ["0", "4", "5"]
```

Happy learning!! 💪