Real World Example

User Roles in an Admin Panel

Banking apps and admin dashboards have roles like viewer, editor and admin. Here an enum defines roles and a permission table decides what each role can do.

Example

enum Role {
  Viewer = "VIEWER",
  Support = "SUPPORT",
  Admin = "ADMIN",
}

type Action = "viewOrders" | "refund" | "deleteUser";

const permissions: Record<Role, Action[]> = {
  [Role.Viewer]: ["viewOrders"],
  [Role.Support]: ["viewOrders", "refund"],
  [Role.Admin]: ["viewOrders", "refund", "deleteUser"],
};

function can(role: Role, action: Action): boolean {
  return permissions[role].includes(action);
}

for (const role of Object.values(Role)) {
  console.log(role.padEnd(8), "refund:", can(role, "refund"), "| deleteUser:", can(role, "deleteUser"));
}

Output

VIEWER   refund: false | deleteUser: false
SUPPORT  refund: true | deleteUser: false
ADMIN    refund: true | deleteUser: true

Note: Record<Role, Action[]> forces you to list permissions for every role. Add a new role to the enum and the compiler reminds you to update this table.