I have a binary string which I want to convert to the equivalent flag enum value. My attempt:
const permissionNum = parseInt(this.auth.decodedToken.permissions, 2);
const userPermissions: PermissionFlags = PermissionFlags[PermissionFlags[permissionNum]];
and this is the 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
}
This does work as long as it is a single flag. So if the string is 00111000
this is parsed to 56 but userPermissions
stays undefined. Is that not possible in Typescript?
Enums in TypeScript work a bit differently compared to those in C#. After all, they are compiled down to a simple JavaScript object with indexing based on the names and values. Therefor, that object will not contain a valid entry for the index that is the combination of multiple flags, but only for the individual flag values.
For example, your enum declaration will compile to the following 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 = {}));
If you now index into the PermissionFlags
object with the index 56, you get undefined
as no value is defined for that specific index.
I would rather use the approach in the following code snippet:
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);