什么是TypeScript中的枚举标志?

时间:2016-09-07 00:45:55

标签: javascript typescript

我使用this ebook作为参考来学习TypeScript。我已经检查了TypeScript Official Documentation,但我找不到有关枚举标记的信息。

4 个答案:

答案 0 :(得分:43)

它们是一种有效存储和表示布尔值集合的方法。

例如,取这个标志枚举:

enum Traits {
    None = 0,
    Friendly = 1 << 0, // 0001 -- the bitshift is unnecessary, but done for consistency
    Mean = 1 << 1,     // 0010
    Funny = 1 << 2,    // 0100
    Boring = 1 << 3,   // 1000
    All = ~(~0 << 4)   // 1111
}

而不是只能像这样表示单个值:

let traits = Traits.Mean;

我们可以在一个变量中表示多个值:

let traits = Traits.Mean | Traits.Funny; // (0010 | 0100) === 0110

然后单独测试它们:

if (traits & Traits.Mean) {
    console.log(":(");
}

答案 1 :(得分:12)

官方文档有这个例子,我将添加一些对使用枚​​举和标志至关重要的细节。

enum FileAccess {
    None,
    Read    = 1 << 1,
    Write   = 1 << 2,
}

在TypeScript中,您可以直接使用=

指定值
let x:FileAccess = FileAccess.Read;

但这可能会覆盖以前的值。要解决此问题,您可以使用|=附加标记。

x |= FileAccess.Write;

此时,变量x是读写。您可以使用&号和波浪号删除值:

x &= ~FileAccess.Read;

最后,您可以比较以查看是否将其中一个值设置为变量。接受的答案是不对的。它不应该只使用&符号,还要检查===所需的值。原因是&符号返回一个数字,而不是布尔值。

console.log(FileAccess.Write === (x & FileAccess.Write)); // Return true
console.log(FileAccess.Read === (x & FileAccess.Read)); // Return false

答案 2 :(得分:1)

您可以check this solution,添加一些基础知识,但是如果您要大量使用它,它的用法就很好:

let FlaggedExample: IFlaggedEnum = FlaggedEnum.create(Example, 1 << 2);  // class definition

let example = new FlaggedExample(3); // Alpha,Beta instance of the class
export module FlaggedEnum {
    "use strict";
    export interface IFlaggedEnumGenerator {
        (_enum: any, _max: number): IFlaggedEnum;
    }

    export interface IFlaggedEnum {
        (val: IFlaggedEnum): void;
        (val: number): void;
        (val: string): void;

        /** array of the individual enum flags that represent the value 
         */
        toArray(): IFlaggedEnum[];

        /** does this instance contain all the flags of the value 
         */
        contains(val: IFlaggedEnum): boolean;
        contains(val: number): boolean;
        contains(val: string): boolean;

        /** adds the flags to the value and returns a new instance 
         */
        add(val: IFlaggedEnum): IFlaggedEnum;
        add(val: number): IFlaggedEnum;
        add(val: string): IFlaggedEnum;

        /** removes the flags from the value and returns a new instance 
         */
        remove(val: IFlaggedEnum): IFlaggedEnum;
        remove(val: number): IFlaggedEnum;
        remove(val: string): IFlaggedEnum;

        /** returns an instance containing all intersecting flags 
         */
        intersect(val: IFlaggedEnum): IFlaggedEnum;
        intersect(val: number): IFlaggedEnum;
        intersect(val: string): IFlaggedEnum;

        /** does the two instances equal each other 
         */
        equals(val: IFlaggedEnum): boolean;
        equals(val: number): boolean;
        equals(val: string): boolean;

    }

    /** create a class definition for a Flagged Enum
     * @method create
     * @param _enum {enum} The enum definition being exteded
     * @param _max {number} the maximum possible value of the enum being extended
     * @returns {IFlaggedEnum} the class definition for the provided enum
     */
    export var create: IFlaggedEnumGenerator = function (_enum: any, _max: number): IFlaggedEnum {

        var base: any = _enum,
            max: number = _max;

        var Base: IFlaggedEnum = <any>function (val: any): void {
            if (typeof (val) === "string") {
                val = base[val];
            }
            this.value = val + 0;
        };

        var proto: any = Base.prototype;

        proto.valueOf = function (): number { return <number>this.value; };
        proto.toString = function (): string {
            var list: string[] = [];
            for (var i: number = 1; i < max; i = i << 1) {
                if ((this.value & i) !== 0) {
                    list.push(base[i]);
                }
            }
            return list.toString();
        };

        proto.toArray = function (): IFlaggedEnum[] {
            var list: IFlaggedEnum[] = [];
            for (var i: number = 1; i < max; i = i << 1) {
                if ((this.value & i) !== 0) {
                    list.push(new Base(i));
                }
            }
            return list;
        };

        proto.contains = function (val: any): boolean {
            if (typeof (val) === "string") {
                val = base[val];
            }
            return (this.value & val) === (val + 0);
        };

        proto.add = function (val: any): IFlaggedEnum {
            if (typeof (val) === "string") {
                val = base[val];
            }
            return new Base(this.value | val);
        };

        proto.remove = function (val: any): IFlaggedEnum {
            if (typeof (val) === "string") {
                val = this.base[val];
            }
            return new Base((this.value ^ val) & this.value);
        };

        proto.intersect = function (val: any): IFlaggedEnum {
            if (typeof (val) === "string") {
                val = base[val];
            }
            var final: number = 0;
            for (var i: number = 1; i < max; i = (i << 1)) {
                if ((this.value & i) !== 0 && (val & i) !== 0) {
                    final += i;
                }
            }
            return new Base(final);
        };

        proto.equals = function (val: any): boolean {
            if (typeof (val) === "string") {
                val = base[val];
            }
            return this.value === (val + 0);
        };

        return Base;

    };
}

答案 3 :(得分:0)

标志允许您检查一组条件中的某个条件是否为真。这是各种其他编程语言中的通用编程模式,例如这是一个关于C#的示例:Using Bitwise operators on flags