DEV Community

Cover image for Merge TypeScript Enums
Afraz Khan
Afraz Khan

Posted on • Edited on

Merge TypeScript Enums

There is no native support for merging 2 or more enums in typescript but its possible with a combination of type aliases and enums.

Merge Enums

  • Let suppose, you have 2 string based enums:
// enum 1
enum ManagedUserStatus {
  M_STATUS1 = 'M_STATUS1',
  M_STATUS2 = 'M_STATUS2',
  M_STATUS3 = 'M_STATUS3',
}

// enum 2
enum SystemUserStatus {
  Sys_STATUS1 = 'Sys_STATUS1',
  Sys_STATUS2 = 'Sys_STATUS2',
  Sys_STATUS3 = 'Sys_STATUS3',
}
Enter fullscreen mode Exit fullscreen mode
  • Convert the enums into a single javascript object, lets call it enum object. Utilize the enum object in your codebase as a regular enum. This object has the union of all enums combined.
// same enum like values
export const UserStatuses = { ...ManagedUserStatus,
 ...SystemUserStatus }

// OR

// Kind of nested enum approach
export const UserStatuses = { ManagedUserStatus,
 SystemUserStatus }
Enter fullscreen mode Exit fullscreen mode
  • Create a type from the enum object. Use this type as the regular enum type in your codebase.

Name of this type alias can be same as the enum object or anything else.

// 1. export as an object type
export type UserStatus = typeof UserStatuses;

// OR

// 2. export only the keys
export type UserStatus = keyof typeof UserStatuses;

// OR

// 3. export as a uinon type
export type UserStatus = ManagedUserStatus | SystemUserStatus;
Enter fullscreen mode Exit fullscreen mode

This way, you can merge 2 or more enums and simulate the same enum like behavior in your codebase.

Sample usage

Lets imagine a method in your code which utilizes our newly created enum.

function confirmUser(status: UserStatus){
    if(status === UserStatuses.M_STATUS2){
        return false;
    }
}
Enter fullscreen mode Exit fullscreen mode

Merge Issues

There are some limitations and issues with this kind of merge and you have to be aware of them before merging your enums.

Numbered Enums

With numbered enums, you will have duplicate values in the enum object.

enum ManagedUserStatus {
  M_STATUS1,    // 0
  M_STATUS2,    // 1
  M_STATUS3     // 2
}

// enum 2
enum SystemUserStatus {
  Sys_STATUS1,  // 0
  Sys_STATUS2,  // 1
  Sys_STATUS3   // 2
}

const UserStatuses = { ...ManagedUserStatus,
...SystemUserStatus };

type UserStatuses = typeof UserStatuses;
Enter fullscreen mode Exit fullscreen mode

Make sure that, if you need unique values then assign proper initializers to your enums like below:

enum ManagedUserStatus {
  M_STATUS1,    // 0
  M_STATUS2,    // 1
  M_STATUS3     // 2
}

// enum 2
enum SystemUserStatus {
  Sys_STATUS1 = 6,  // 6
  Sys_STATUS2,      // 7
  Sys_STATUS3       // 8
}
Enter fullscreen mode Exit fullscreen mode

Duplicate Keys

If your enums have duplicate keys then that key in the final enum object has over-written value. See below exmple

enum ManagedUserStatus {
  M_STATUS1,    // 0
  M_STATUS2,    // 1
  M_STATUS3     // 2
}

// enum 2
enum SystemUserStatus {
  Sys_STATUS1,  // 0
  M_STATUS2 = 'CONFIRMED',
  Sys_STATUS3 = 'UNCONFIRMED'
}

const UserStatuses = { ...ManagedUserStatus, 
...SystemUserStatus };

type UserStatuses = typeof UserStatuses;

const m_status2_value = UserStatuses.M_STATUS2; //  'CONFIRMED'
Enter fullscreen mode Exit fullscreen mode

Nested Enums

If you plan to use the nested enums for the enum object then maybe you can ignore above issues because there is no actual merging process in that case. only key based enums are exported out of the enum object. See below

enum ManagedUserStatus {
  M_STATUS1,    // 0
  M_STATUS2,    // 1
  M_STATUS3     // 2
}

// enum 2
enum SystemUserStatus {
  Sys_STATUS1,  // 0
  M_STATUS2 = 'CONFIRMED',
  Sys_STATUS3 = 'UNCONFIRMED'
}

const UserStatuses = { ManagedUserStatus, 
SystemUserStatus };

type UserStatuses = typeof UserStatuses;

// no effect of duplicate keys
const mStatus2_one = UserStatuses.ManagedUserStatus. M_STATUS2; //  '1'
const mStatus2_two = UserStatuses.SystemUserStatus. M_STATUS2; //  'CONFIRMED'

// no effect of numbered values
const sysStatus1 = UserStatuses.SystemUserStatus. Sys_STATUS1; //  '0'
Enter fullscreen mode Exit fullscreen mode

happy learning! 👊

Top comments (1)

Collapse
 
jangelodev profile image
João Angelo

Hi Afraz Khan,
Excellent content, very useful.
Thanks for sharing.