如何设计支持权限继承的TypeScript枚举索引操作表类型
符合需求的TypeScript实现方案
最适配的是基于Record的嵌套映射结构,配合封装继承查询逻辑即可完全满足三个核心需求,具体实现如下:
第一步:定义基础枚举与类型
首先按权限从低到高定义角色、工单状态枚举,以及操作类型:
// 角色枚举,按权限升序排列 enum Role { Engineer, TeamLeader, Manager, Director } // 工单状态枚举 enum TicketStatus { NewRequest, LiveRequest, UnderReview, Completed } // 工单操作类型,可按业务扩展 type TicketAction = "Claim" | "Submit for review" | "Approve" | "Reject" | "Close"
第二步:核心权限矩阵类型
使用两层Record嵌套定义权限矩阵,天然支持枚举作为索引,完全符合你需要的高可读性赋值方式:
type PermissionMatrix = Record<Role, Record<TicketStatus, TicketAction[]>>
你提到的赋值形式可以直接使用,完全符合类型约束:
// 示例赋值 const permissionMatrix: Partial<PermissionMatrix> = {} permissionMatrix[Role.Engineer] = permissionMatrix[Role.Engineer] || {} permissionMatrix[Role.Engineer][TicketStatus.NewRequest] = ["Claim"] permissionMatrix[Role.Engineer][TicketStatus.LiveRequest] = ["Submit for review"]
第三步:实现权限自动继承
因为角色是按权限从低到高排序的,只需要封装统一的查询方法,自动合并当前角色及所有低阶角色的操作即可:
// 角色层级顺序,保证低阶角色在前 const ROLE_HIERARCHY = [Role.Engineer, Role.TeamLeader, Role.Manager, Role.Director] // 封装权限服务简化使用 class TicketPermissionService { private matrix: Partial<PermissionMatrix> = {} // 配置权限,可读性极强,领域专家可直接核验 setActions(role: Role, status: TicketStatus, actions: TicketAction[]) { if (!this.matrix[role]) this.matrix[role] = {} as Record<TicketStatus, TicketAction[]> this.matrix[role][status] = actions } // 查询带自动继承的可用操作 getAvailableActions(role: Role, status: TicketStatus): TicketAction[] { // 拿到当前角色及所有权限更低的角色列表 const allowedRoles = ROLE_HIERARCHY.slice(0, ROLE_HIERARCHY.indexOf(role) + 1) // 合并所有符合条件角色的操作并去重 const actionSet = new Set<TicketAction>() allowedRoles.forEach(r => { const roleActions = this.matrix[r]?.[status] || [] roleActions.forEach(action => actionSet.add(action)) }) return Array.from(actionSet) } }
使用示例
const permissionService = new TicketPermissionService() // 配置权限 permissionService.setActions(Role.Engineer, TicketStatus.NewRequest, ["Claim"]) permissionService.setActions(Role.TeamLeader, TicketStatus.UnderReview, ["Approve", "Reject"]) permissionService.setActions(Role.Manager, TicketStatus.Completed, ["Close"]) // 查询经理在待审核状态的操作,自动继承工程师、团队负责人的权限 console.log(permissionService.getAvailableActions(Role.Manager, TicketStatus.UnderReview)) // 输出:["Claim", "Approve", "Reject"]
方案优势
- 完全类型安全:所有索引均为枚举,TS会自动校验枚举值错误,避免运行时问题
- 配置可读性极高:每行配置对应单个角色单个状态的操作列表,领域专家无需懂代码也能直接核验
- 继承逻辑统一维护:无需重复配置高阶角色的低阶权限,新增角色仅需在
ROLE_HIERARCHY对应位置插入即可,维护成本极低
内容的提问来源于stack exchange,提问作者ianmayo
相关产品推荐
相关产品推荐

