将二进制字符串转换为typescript中的标志

dojqjjoe  于 2023-08-07  发布在  TypeScript
关注(0)|答案(3)|浏览(142)

我有一个二进制字符串,我想转换为等效的标志枚举值。我的尝试:

const permissionNum = parseInt(this.auth.decodedToken.permissions, 2);
const userPermissions: PermissionFlags = PermissionFlags[PermissionFlags[permissionNum]];

字符串
这就是enum:

export enum PermissionFlags {
  None = 0,
  RemoveMember = 1 << 0,
  Invite = 1 << 1,
  EditArticleSettings = 1 << 2,
  CheckOut = 1 << 3,
  CheckIn = 1 << 4,
  CanView = 1 << 5,
  IsOwner = 1 << 6,
  xxx = 1 << 7
}


只要它是一个单一的标志,它就可以工作。因此,如果字符串是00111000,则解析为56,但userPermissions保持未定义。这在Typescript中是不可能的。

wooyq4lh

wooyq4lh1#

TypeScript中的枚举与C#中的枚举工作方式略有不同。毕竟,它们被编译成一个简单的JavaScript对象,并基于名称和值进行索引。因此,该对象将不包含作为多个标志的组合的索引的有效条目,而仅包含单个标志值的有效条目。
例如,枚举声明将编译为以下JavaScript:

export var PermissionFlags;
(function (PermissionFlags) {
    PermissionFlags[PermissionFlags["None"] = 0] = "None";
    PermissionFlags[PermissionFlags["RemoveMember"] = 1] = "RemoveMember";
    PermissionFlags[PermissionFlags["Invite"] = 2] = "Invite";
    PermissionFlags[PermissionFlags["EditArticleSettings"] = 4] = "EditArticleSettings";
    PermissionFlags[PermissionFlags["CheckOut"] = 8] = "CheckOut";
    PermissionFlags[PermissionFlags["CheckIn"] = 16] = "CheckIn";
    PermissionFlags[PermissionFlags["CanView"] = 32] = "CanView";
    PermissionFlags[PermissionFlags["IsOwner"] = 64] = "IsOwner";
    PermissionFlags[PermissionFlags["xxx"] = 128] = "xxx";
})(PermissionFlags || (PermissionFlags = {}));

字符串
如果你现在用索引56索引PermissionFlags对象,你会得到undefined,因为没有为那个特定的索引定义值。
我宁愿使用下面代码片段中的方法:

export enum PermissionFlags {
  None = 0,
  RemoveMember = 1 << 0,
  Invite = 1 << 1,
  EditArticleSettings = 1 << 2,
  CheckOut = 1 << 3,
  CheckIn = 1 << 4,
  CanView = 1 << 5,
  IsOwner = 1 << 6,
  xxx = 1 << 7
}

export function hasPermission(userPermissions: number | string, flags: PermissionFlags): boolean {
  const perm = typeof userPermissions === "number" ? userPermissions : parseInt(userPermissions, 2);
  return (perm & flags) === flags;
}

// Check for permissions by specifying the user permission mask and the target permission flags
const canInvite = hasPermission("00111000", PermissionFlags.Invite);
const canCheckInAndIsOwner = hasPermission(56, PermissionFlags.CheckIn | PermissionFlags.IsOwner);
// Could even call it with PermissionFlags as first argument as those are basically numbers
const canCheckOut = hasPermission(PermissionFlags.CheckOut | PermissionFlags.IsOwner, PermissionFlags.CheckOut);

yjghlzjz

yjghlzjz2#

function getPermissions(val :number| PermissionFlags) : number[] {
var res = Object.keys(PermissionFlags)
.filter(t=> typeof t !== "number" && val & +t)
.map(t=>+t);
return res; 
}
var r = PermissionFlags.CheckIn | PermissionFlags.IsOwner;
var q = getPermissions(r);
console.log(q[0] === PermissionFlags.CheckIn)
console.log(q[1] === PermissionFlags.IsOwner)

字符串
基本上得到枚举的值。apply has flag with“瓦尔& t”expression返回匹配的值。你可能不想返回一个数组,所以你可以这样做:

let flags =0;
res.forEach(r=> flags|=r);
return flags;


有趣的是,如果你知道你的号码是有效的,你可以直接将它转换为枚举。

c3frrgcw

c3frrgcw3#

Anon回答很好,但要小心,里面有一个安全问题。线

const canCheckInAndIsOwner = hasPermission(56, PermissionFlags.CheckIn | PermissionFlags.IsOwner);

字符串
不会像它说的那样,实际上它将是canCheckInOrIsOwner。如果你希望它是and而不是or,你应该替换这行:

return (perm & flags) !== 0;


return (perm & flags) === flags;

相关问题