TypeScript如何运行时校验变量是否属于指定字符串字面量联合类型
TypeScript 所有类型仅在编译期存在,运行时会被完全擦除,所以无法直接用'a_1_1_0' | 'a_1_0_0'这个联合类型做运行时判断。你需要先把允许的字面量定义为运行时真实存在的常量集合,再从常量反向推导类型,保证编译期类型和运行时校验逻辑完全一致。
具体实现方案如下:
- 第一步:定义允许的v值只读数组,这是运行时真实存在的变量
const ALLOWED_V_VALUES = ['a_1_0_0', 'a_1_1_0'] as const;
- 第二步:从数组推导对应的联合类型,替代你原来手写的字面量联合
type TV = typeof ALLOWED_V_VALUES[number]; // 自动推导为 'a_1_0_0' | 'a_1_1_0'
- 第三步:编写类型守卫函数,同时满足运行时校验和编译期类型收窄的需求
function isValidV(value: unknown): value is TV { return typeof value === 'string' && ALLOWED_V_VALUES.includes(value as TV); }
完整使用示例:
interface a_1_0_0 { v: 'a_1_0_0' }; interface a_1_1_0 { v: 'a_1_1_0' }; type T = a_1_0_0 | a_1_1_0; function func(foo: T['v']) { // 函数内部做校验 if (!isValidV(foo)) { throw new Error(`非法的v值:${foo}`); } // 后续逻辑里foo的类型会被自动收窄为 'a_1_0_0' | 'a_1_1_0',不需要额外做类型断言 } // 动态赋值场景(值来自接口、用户输入等TS无法做静态检查的场景) const dynamicFoo = (Math.random() > 0.5 ? 'a_0_0_0' : 'a_1_0_0') as unknown as T['v']; func(dynamicFoo);
你也可以选择在调用func之前先调用isValidV做前置校验,避免传入非法值。
内容的提问来源于stack exchange,提问作者DocuDaniel
相关产品推荐
相关产品推荐

