将二进制字符串转换为打字稿中的标志
Convert binary string to flags in typescript
我有一个二进制字符串,我想将其转换为等效的标志枚举值。我的尝试:
const permissionNum = parseInt(this.auth.decodedToken.permissions, 2);
const userPermissions: PermissionFlags = PermissionFlags[PermissionFlags[permissionNum]];
这是枚举:
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 中是不可能的吗?
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) !== 0;
}
// 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);
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 具有带有 "val & t" 表达式 return 匹配值的标志。你可能不想 return 一个数组,所以你可以这样做:
let flags =0;
res.forEach(r=> flags|=r);
return flags;
有趣的是,如果你知道你的号码是有效的,你可以直接将它转换为枚举。
匿名回答很好,但要小心,里面有安全问题。
行
const canCheckInAndIsOwner = hasPermission(56, PermissionFlags.CheckIn | PermissionFlags.IsOwner);
不会按照它说的去做,事实上它会 canCheckInOrIsOwner
。
如果您希望它是 and
而不是 or
,您应该替换行:
return (perm & flags) !== 0;
来自
return (perm & flags) === flags;
我有一个二进制字符串,我想将其转换为等效的标志枚举值。我的尝试:
const permissionNum = parseInt(this.auth.decodedToken.permissions, 2);
const userPermissions: PermissionFlags = PermissionFlags[PermissionFlags[permissionNum]];
这是枚举:
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 中是不可能的吗?
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) !== 0;
}
// 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);
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 具有带有 "val & t" 表达式 return 匹配值的标志。你可能不想 return 一个数组,所以你可以这样做:
let flags =0;
res.forEach(r=> flags|=r);
return flags;
有趣的是,如果你知道你的号码是有效的,你可以直接将它转换为枚举。
匿名回答很好,但要小心,里面有安全问题。 行
const canCheckInAndIsOwner = hasPermission(56, PermissionFlags.CheckIn | PermissionFlags.IsOwner);
不会按照它说的去做,事实上它会 canCheckInOrIsOwner
。
如果您希望它是 and
而不是 or
,您应该替换行:
return (perm & flags) !== 0;
来自
return (perm & flags) === flags;