TypeScript中如何将Exclude生成的联合类型转换为可用的子枚举?
TypeScript 中的类型定义会在编译后被擦除,所以你之前通过Exclude得到的ErrorErrcode只能用作类型标注,无法在运行时代码中作为值访问。要实现可作为值使用的子枚举,可参考以下两种方案:
方案1:手动构造子枚举对象(适合枚举项少的场景)
直接复用原枚举的值构造字面量对象,再从对象反向提取类型,兼顾类型校验和运行时取值能力:
// 原枚举,若不需要const enum的编译优化可去掉const修饰符,保留原枚举的运行时对象 enum Errcode{ Ok=0, Error=1, AccessDeny=201, PostsNotFound=202, TagNotFound=203, } // 构造子枚举值对象 const ErrorErrcode = { Error: Errcode.Error, AccessDeny: Errcode.AccessDeny, PostsNotFound: Errcode.PostsNotFound, TagNotFound: Errcode.TagNotFound } as const; // 从值对象提取对应类型,效果和你之前用Exclude得到的类型完全一致 type ErrorErrcode = typeof ErrorErrcode[keyof typeof ErrorErrcode]; // 使用示例 // 作为值使用 console.log(ErrorErrcode.AccessDeny); // 输出 201 // 作为类型使用 const err: ErrorErrcode = ErrorErrcode.PostsNotFound;
方案2:通用过滤函数生成子枚举(适合枚举项多的场景)
如果原枚举项很多,手动逐个写子枚举成员太繁琐,可以封装通用过滤函数,自动从原枚举中剔除不需要的项生成子枚举:
enum Errcode{ Ok=0, Error=1, AccessDeny=201, PostsNotFound=202, TagNotFound=203, } /** * 从原枚举中排除指定值,生成子枚举对象 * @param originEnum 原枚举 * @param excludeValues 需要排除的枚举值列表 */ function createSubEnum<T extends object, K extends T[keyof T]>(originEnum: T, excludeValues: K[]) { const subEnum = {} as Omit<T, keyof T>; for (const [key, value] of Object.entries(originEnum)) { if (!excludeValues.includes(value as K)) { // @ts-ignore 运行时逻辑安全,忽略类型检查报错 subEnum[key] = value; } } return subEnum as Readonly<Omit<T, {[P in keyof T]: T[P] extends K ? P : never}[keyof T]>>; } // 生成排除Ok的错误码子枚举 const ErrorErrcode = createSubEnum(Errcode, [Errcode.Ok]); // 提取子枚举类型 type ErrorErrcode = typeof ErrorErrcode[keyof typeof ErrorErrcode]; // 使用示例 console.log(ErrorErrcode.TagNotFound); // 输出 203 const err: ErrorErrcode = ErrorErrcode.Error;
补充说明
如果你的原枚举必须使用const enum(用于压缩打包体积),第一种手动构造的方案依然可以正常使用,因为const enum的成员值会在编译阶段替换为字面量,不会影响子枚举对象的运行时逻辑。
内容的提问来源于stack exchange,提问作者tangir miah
相关产品推荐
相关产品推荐

