我使用this ebook作为参考来学习TypeScript。我已经检查了TypeScript Official Documentation,但我找不到有关枚举标记的信息。
答案 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