如何判断TypeScript中字符串变量所属的联合类型?
解决方案:从常量数组推导联合类型 + 类型守卫
在TypeScript中,你可以通过从常量数组自动推导联合类型,再配合自定义类型守卫的方式,既实现运行时类型检查,又充分利用TypeScript的类型系统,避免重复定义。
步骤1:定义常量数组并自动推导联合类型
首先用as const定义只读的常量数组,TypeScript会自动推导数组元素的字面量类型,接着通过typeof 数组名[number]生成对应的联合类型。这样你只需要维护数组,联合类型会自动更新,无需重复编写:
// 定义运行时可用的常量数组,as const 确保TypeScript保留字面量类型 const TYPE1_VALUES = ["a", "b", "c"] as const; // 从数组自动推导联合类型 Type1 = "a" | "b" | "c" type Type1 = typeof TYPE1_VALUES[number]; const TYPE2_VALUES = ["x", "y", "z"] as const; type Type2 = typeof TYPE2_VALUES[number];
步骤2:使用自定义类型守卫做运行时检查
为了让TypeScript在运行时检查后自动缩小参数类型,你可以写一个简单的类型守卫函数:
// 自定义类型守卫:判断参数是否属于Type1 function isType1(param: unknown): param is Type1 { // 用类型断言避免类型报错,因为includes只接受Type1类型的参数 return TYPE1_VALUES.includes(param as Type1); }
步骤3:在函数中使用类型守卫
现在在doSomething里调用类型守卫,TypeScript会自动识别参数的类型分支,提供完整的类型检查:
function doSomething(param: Type1 | Type2) { if (isType1(param)) { // 此处param被TypeScript推断为Type1类型,类型检查生效 functionForTypeOne(param); } else { // 此处param自动推断为Type2类型 functionForTypeTwo(param); } } // 示例函数,接受明确的Type1/Type2类型参数 function functionForTypeOne(arg: Type1) { console.log(`处理Type1类型:${arg}`); } function functionForTypeTwo(arg: Type2) { console.log(`处理Type2类型:${arg}`); } // 调用示例 doSomething("a"); // 触发functionForTypeOne doSomething("z"); // 触发functionForTypeTwo
简化版(无需单独类型守卫)
如果不需要复用类型检查逻辑,也可以直接在条件判断中使用类型断言,TypeScript同样能正确缩小类型:
function doSomething(param: Type1 | Type2) { if (TYPE1_VALUES.includes(param as Type1)) { functionForTypeOne(param); } else { functionForTypeTwo(param); } }
方案优势
- 避免重复定义:只需要维护常量数组,联合类型自动推导,减少冗余代码
- 类型检查完整:TypeScript能在分支中自动识别参数类型,避免类型错误
- 运行时可靠:基于数组的
includes方法实现运行时检查,逻辑清晰高效
内容的提问来源于stack exchange,提问作者Sphygmus
相关产品推荐
相关产品推荐

