TypeScript通用枚举方法:按角色返回指定枚举值列表
枚举值的角色权限过滤实现方案
针对你需要实现的「返回指定枚举全部值,或根据用户角色返回指定枚举项」的需求,结合你遇到的TypeScript类型问题,提供两个可行的实现思路:
方案一:函数重载 + 枚举实例传入
通过函数重载处理两种调用场景(仅传枚举 / 传枚举+角色+指定项),同时传入枚举的实际对象解决类型与值分离的问题:
// 先定义角色枚举和业务枚举示例 enum UserRole { Admin = 'admin', Regular = 'regular' } enum Permission { Read = 'read', Write = 'write', Delete = 'delete' } // 重载签名1:仅传入枚举,返回全部枚举值 function getItemsBasedOnRole<T extends Record<string, string | number>>(enumObj: T): Array<T[keyof T]>; // 重载签名2:传入枚举、角色、指定项,返回过滤后的结果 function getItemsBasedOnRole<T extends Record<string, string | number>>(enumObj: T, role: UserRole, items: Array<T[keyof T]>): Array<T[keyof T]>; // 核心实现 function getItemsBasedOnRole<T extends Record<string, string | number>>(enumObj: T, role?: UserRole, items?: Array<T[keyof T]>): Array<T[keyof T]> { // 无角色和指定项时,返回枚举全部值(过滤数字键,兼容数字枚举的反向映射) if (!role && !items) { return Object.values(enumObj).filter(val => typeof val !== 'number') as Array<T[keyof T]>; } // 根据角色逻辑过滤,这里可替换为你的实际权限规则 if (role === UserRole.Admin) { return items || []; } else { // 示例:普通用户仅保留Read权限 return items?.filter(item => item === Permission.Read) || []; } } // 调用示例 console.log(getItemsBasedOnRole(Permission)); // 输出: ["read", "write", "delete"] console.log(getItemsBasedOnRole(Permission, UserRole.Admin, [Permission.Read, Permission.Delete])); // 输出: ["read", "delete"] console.log(getItemsBasedOnRole(Permission, UserRole.Regular, [Permission.Read, Permission.Delete])); // 输出: ["read"]
关键解决点:
- 枚举类型约束:用
Record<string, string | number>替代{[s: number]: string},更贴合枚举的键值结构(枚举键为字符串,值支持字符串/数字) - 枚举值获取:传入枚举的实际对象(如
Permission),而非类型,这样就能通过Object.values获取枚举值 - 可选参数问题:通过函数重载明确两种调用模式,规避TypeScript不支持可选剩余元组的限制
方案二:拆分单一职责函数
将「获取全部枚举值」和「角色过滤」拆分为两个独立函数,职责更清晰,类型处理更简单:
// 获取枚举全部值的通用函数 function getAllEnumValues<T extends Record<string, string | number>>(enumObj: T): Array<T[keyof T]> { return Object.values(enumObj).filter(val => typeof val !== 'number') as Array<T[keyof T]>; } // 根据角色过滤指定枚举项的函数 function getFilteredItemsByRole<T>(role: UserRole, items: T[]): T[] { if (role === UserRole.Admin) { return items; } else { // 替换为你的实际权限过滤逻辑 return items.filter(item => item === Permission.Read) as T[]; } } // 调用示例 const allPermissions = getAllEnumValues(Permission); const adminPermissions = getFilteredItemsByRole(UserRole.Admin, [Permission.Read, Permission.Delete]); const regularPermissions = getFilteredItemsByRole(UserRole.Regular, [Permission.Read, Permission.Delete]);
优势:
- 函数职责单一,可读性和可维护性更强
- 避免复杂的重载和可选参数类型处理,降低出错概率
内容的提问来源于stack exchange,提问作者Mihai Socaciu
相关产品推荐
相关产品推荐

