0

As the title suggests, I'm wondering if there's a way to do a similar thing as in C# with flag enums, where if the object is printed to IO, it prints out the flags that are active, instead of an integer they accumulate to. Let's say I have a flag enum and an object with that enum as follows:

enum Weekdays {
 None = 0,
 Monday = 1 << 0,
 Tuesday = 1 << 1,
 Wednesday = 1 << 2, 
 Thursday = 1 << 3,
 Friday = 1 << 4,
 Saturday = 1 << 5,
 Sunday = 1 << 6
}
let obj = {
 workdays: Weekdays.Monday | Weekdays.Tuesday | Weekdays.Wednesday | Weekdays.Thursday | Weekdays.Friday
}

If I would to console.log this object now, I'd get the following:

{
 "workdays": 31
}

Of course I could iterate through the whole enum and check flags like that:

if ((obj.workdays & Weekdays.Monday) === Weekdays.Monday)

But that seems very inefficient, especially if I increase the size of the enum.

So the question is: Is there a more elegant way to check for active flags of an enum in an object?

I tried to write a generic function where I could just put an enum in and an object which values I want to check, but I didn't get far due to being pretty new to the language. I've also, naturally, searched the web for any solutions or at least hints of possible solutions, but couldn't find much except the flag check.

Galgarius
  • 1
  • 2
  • you need to write your own utility function to print active flags. There is no such feature in JS. Btw, don't be confused by TS and JS. `Enum` is strict TS feature and console.log is not a part of neither TS nor JS, it is a part of Browser API – captain-yossarian from Ukraine Jan 09 '23 at 10:17
  • 1
    alright, that answers my question. Thank you! I came up with my own solution that seems promising. I will post it when I get it working. – Galgarius Jan 09 '23 at 10:56
  • So, kinda like bitfields? – kelsny Jan 09 '23 at 14:58

1 Answers1

0

Since there's no such feature, I read some more documentation and tried implementing the solution myself. Here's the solution:

function getSelectedEnumMembers<T extends Record<keyof T, number>>(enumType: T, value: number): Extract<keyof T, string>[] {
    function hasFlag(value: number, flag: number): boolean {
        return (value & flag) === flag;
    }

    const selectedMembers: Extract<keyof T, string>[] = [];
    for (const member in enumType) {
        if (hasFlag(value, enumType[member])) {
        selectedMembers.push(member);
        }
    }
    return selectedMembers;
}

Hope it helps other people who somehow end up in my situation.

Galgarius
  • 1
  • 2