TypeScript中遍历枚举时如何排除命名空间内的静态函数?
嘿,这个坑我之前踩过!当你把枚举和同名命名空间结合使用时,TypeScript会把枚举成员和命名空间里的静态方法都挂载到同一个对象上,所以用Object.keys(Foo)遍历的时候,自然会把getAllEnumTypes这类方法也当成键包含进去。下面给你几个实用的解决思路:
方法一:过滤掉非枚举成员(通用方案)
针对数字枚举和字符串枚举,我们可以通过过滤规则剔除掉反向映射的键和静态方法。以数字枚举为例:
export enum Foo { Bar, Baz } export namespace Foo { export const getAllEnumTypes = (): Foo[] => { return Object.keys(Foo) // 过滤掉数字字符串(数字枚举的反向映射)和静态方法 .filter(key => isNaN(Number(key)) && typeof Foo[key] !== 'function') .map(key => Foo[key] as Foo); }; }
如果是字符串枚举(没有反向映射),只需要过滤掉函数类型的成员即可:
export enum Foo { Bar = "BAR", Baz = "BAZ" } export namespace Foo { export const getAllEnumTypes = (): Foo[] => { return Object.keys(Foo) .filter(key => typeof Foo[key] !== 'function') .map(key => Foo[key] as Foo); }; }
方法二:用Object.values简化过滤逻辑
直接遍历对象的值,再剔除掉函数类型的项,代码更简洁:
针对数字枚举:
export enum Foo { Bar, Baz } export namespace Foo { export const getAllEnumTypes = (): Foo[] => { return Object.values(Foo) .filter(val => typeof val !== 'function' && typeof val === 'number') as Foo[]; }; }
针对字符串枚举:
export enum Foo { Bar = "BAR", Baz = "BAZ" } export namespace Foo { export const getAllEnumTypes = (): Foo[] => { return Object.values(Foo) .filter(val => typeof val !== 'function') as Foo[]; }; }
方法三:手动维护枚举成员列表(最稳妥的小枚举方案)
如果你的枚举成员数量不多且变动不频繁,直接手动列出所有成员是最不容易出错的方式:
export enum Foo { Bar, Baz } export namespace Foo { export const getAllEnumTypes = (): Foo[] => { return [Foo.Bar, Foo.Baz]; }; }
这种方式完全避免了遍历带来的意外问题,唯一需要注意的是:当枚举新增/删除成员时,要同步更新这个数组。
内容的提问来源于stack exchange,提问作者Ibrahim Erol
相关产品推荐
相关产品推荐

