如何在TypeScript中提前获取联合类型的类型数量?
在TypeScript中获取联合类型的成员数量并用于运行时判断
核心结论
TypeScript没有内置工具直接获取联合类型的成员数量,但可以通过运行时枚举数组推导类型的方式,实现类型与运行时计数的同步,彻底避免硬编码数字的维护风险。
为什么直接从类型取数量不可行?
TypeScript的类型系统是编译时特性,编译后所有类型信息会被完全擦除,运行时无法访问任何类型相关的数据。所以你示例中const numberOfTypes = NumberOfTypes<unionOfThree>的写法本质上无法实现——类型不能直接赋值给运行时变量。
正确的实现方式
步骤1:用枚举数组定义联合类型的所有成员
只需要维护这一个数组,后续的联合类型和计数都会自动同步:
// 定义所有成员的只读数组(唯一需要修改的地方) const unionOfThreeMembers = ['a', 'b', 'c'] as const; // 从数组自动推导联合类型 type unionOfThree = typeof unionOfThreeMembers[number];
步骤2:直接使用数组的length作为计数
数组的length既是运行时可用的值,类型层面也会被推导为准确的数字:
const numberOfUnionThree = unionOfThreeMembers.length; // 类型为3,运行时值为3 const randomSet: Set<unionOfThree> = new Set(); // 检查Set是否填满 if (randomSet.size === numberOfUnionThree) { console.log('the set is full!'); }
扩展:类型层面的计数工具(仅作参考)
如果你只需要在类型层面获取数量(比如做类型约束),可以用类型编程技巧把联合类型转为元组,再取元组的length:
type UnionToTuple<T> = (T extends any ? (t: T) => void : never) extends (t: infer U) => void ? U[] : never; type NumberOfTypes<T> = UnionToTuple<T>['length']; // 测试 type unionOfFive = 1 | 2 | 7 | 15 | 23; type CountFive = NumberOfTypes<unionOfFive>; // 类型为5
但要注意:这个工具仅适用于字面量联合类型,且无法直接转化为运行时可用的值,所以对你的Set判断场景,还是优先用枚举数组的方案。
总结
- 不要试图从类型反向生成运行时值,TypeScript编译擦除特性决定了这不可行。
- 从运行时枚举数组推导联合类型,是兼顾类型安全和运行时可用性的最优方案,修改成员时无需手动更新计数,彻底避免维护bug。
内容的提问来源于stack exchange,提问作者hakuni
相关产品推荐
相关产品推荐

