TypeScript 如何校验字符串是否为指定interface的键对应的值
解决方案
1. 仅需静态编译阶段校验
直接提取interface的所有属性值的联合类型,给目标变量声明该类型即可,不符合的赋值会直接抛出TS类型错误:
const string = 'world'; const string2 = 'bar'; const string3 = 'test'; interface example { hello: 'world'; foo: 'bar'; }; // 提取example所有属性值的联合类型:'world' | 'bar' type ExampleValidValue = example[keyof example] // 给变量加类型声明 const str1: ExampleValidValue = 'world'; // 校验通过 const str2: ExampleValidValue = 'bar'; // 校验通过 const str3: ExampleValidValue = 'test'; // 直接抛出类型错误:不能将类型“"test"”分配给类型“ExampleValidValue”
2. 需要运行时动态校验
因为TS的interface类型在编译为JS后会被完全擦除,无法在运行时直接读取,所以需要先定义运行时可用的合法值集合,再反向推导TS类型,同时满足静态校验和运行时校验需求:
// 定义运行时可用的合法值集合,用as const保留字面量类型 const EXAMPLE_VALID_VALUES = ['world', 'bar'] as const; // 从合法值集合推导TS类型 type ExampleValidValue = typeof EXAMPLE_VALID_VALUES[number]; // 定义interface时可直接复用该类型,保证类型一致性 interface example { hello: Extract<ExampleValidValue, 'world'>; foo: Extract<ExampleValidValue, 'bar'>; } // 封装类型守卫函数,运行时校验的同时可以让TS自动收窄变量类型 function isExampleValidValue(val: unknown): val is ExampleValidValue { return typeof val === 'string' && EXAMPLE_VALID_VALUES.includes(val as ExampleValidValue); } // 使用示例 const string = 'world'; const string2 = 'bar'; const string3 = 'test'; isExampleValidValue(string) // 返回true,TS自动识别string类型为ExampleValidValue isExampleValidValue(string2) // 返回true isExampleValidValue(string3) // 返回false
内容的提问来源于stack exchange,提问作者Hackel
相关产品推荐
相关产品推荐

