简体   繁体   English

如何在 Typescript 中获取 object 中的标志枚举的活动标志?

[英]How can I get the active flags of a flag enum in an object in Typescript?

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.正如标题所暗示的那样,我想知道是否有一种方法可以用标志枚举来做与 C# 类似的事情,如果 object 被打印到 IO,它会打印出活动的标志,而不是 integer 它们累积到. Let's say I have a flag enum and an object with that enum as follows:假设我有一个标志枚举和一个带有该枚举的 object,如下所示:

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:如果我现在要 console.log 这个 object,我会得到以下信息:

{
 "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?所以问题是:是否有更优雅的方法来检查 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.我尝试编写一个通用的 function,我可以在其中放入一个枚举和一个 object,我想检查哪些值,但由于对这门语言还很陌生,所以我没有走得太远。 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.当然,我也搜索了 web 以寻找任何解决方案或至少可能的解决方案的提示,但除了标志检查之外找不到太多。

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.希望它能帮助那些以某种方式结束在我的情况下的其他人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM