TypeScript中枚举成员判断为何返回false?如何检测变量是否属于枚举
问题:判断字符串枚举成员是否属于目标枚举时返回错误结果
我写了一个判断wallet_type_id是否属于PRETAX_ACCOUNT_TYPES的函数,但传入PRETAX_ACCOUNT_TYPES.FSA时返回了false,代码如下:
enum FOOBAR_ACCOUNT_TYPES { WELLNESS = 'wellness', REWARDS = 'rewards', } enum PRETAX_ACCOUNT_TYPES { TRANSIT = 'transit', PARKING = 'parking', FSA = 'fsa', } const isPretaxAccount = ( wallet_type_id: FOOBAR_ACCOUNT_TYPES | PRETAX_ACCOUNT_TYPES ) => wallet_type_id in PRETAX_ACCOUNT_TYPES; console.log("should be false: ", isPretaxAccount(FOOBAR_ACCOUNT_TYPES.WELLNESS)); // 返回false console.log("should be true: ", isPretaxAccount(PRETAX_ACCOUNT_TYPES.FSA)); // 返回false <--- 错误
原因分析
TypeScript的字符串枚举编译后只会生成「枚举成员名 → 字符串值」的单向映射,不会像数字枚举那样自动生成值到成员名的反向映射。比如PRETAX_ACCOUNT_TYPES编译后的JavaScript对象是:
const PRETAX_ACCOUNT_TYPES = { TRANSIT: 'transit', PARKING: 'parking', FSA: 'fsa' };
in操作符检查的是对象的键名(比如"TRANSIT"、"PARKING"),而你传入的是枚举的字符串值(比如"fsa"),自然匹配不到,所以返回false。
解决方案
方法1:用Object.values()获取枚举值数组后检查
直接提取枚举的所有值,用includes判断传入值是否在其中:
const isPretaxAccount = ( wallet_type_id: FOOBAR_ACCOUNT_TYPES | PRETAX_ACCOUNT_TYPES ) => Object.values(PRETAX_ACCOUNT_TYPES).includes(wallet_type_id);
方法2:提前创建值集合(适合频繁调用场景)
用Set存储枚举值,查询性能更优:
const PRETAX_ACCOUNT_VALUES = new Set(Object.values(PRETAX_ACCOUNT_TYPES)); const isPretaxAccount = ( wallet_type_id: FOOBAR_ACCOUNT_TYPES | PRETAX_ACCOUNT_TYPES ) => PRETAX_ACCOUNT_VALUES.has(wallet_type_id);
方法3:手动添加反向映射
如果需要同时支持通过值查找枚举成员名,可以手动添加反向映射:
enum PRETAX_ACCOUNT_TYPES { TRANSIT = 'transit', PARKING = 'parking', FSA = 'fsa', } // 手动添加值到成员名的反向映射 (PRETAX_ACCOUNT_TYPES as any)[PRETAX_ACCOUNT_TYPES.TRANSIT] = 'TRANSIT'; (PRETAX_ACCOUNT_TYPES as any)[PRETAX_ACCOUNT_TYPES.PARKING] = 'PARKING'; (PRETAX_ACCOUNT_TYPES as any)[PRETAX_ACCOUNT_TYPES.FSA] = 'FSA'; // 此时in操作符可正常生效 const isPretaxAccount = ( wallet_type_id: FOOBAR_ACCOUNT_TYPES | PRETAX_ACCOUNT_TYPES ) => wallet_type_id in PRETAX_ACCOUNT_TYPES;
内容的提问来源于stack exchange,提问作者bigpotato
相关产品推荐
相关产品推荐

