如何将获取的文本文件解析为指定Type并验证类型匹配?
验证JSON是否符合CityJSON类型的方法
一、手动编写类型守卫函数
TypeScript的类型仅存在于编译阶段,运行时需要手动编写逻辑验证数据结构。假设CityJSON有必填字段type(值为"CityJSON")、version(字符串)、CityObjects(非空对象),可以写如下类型守卫:
// 类型守卫函数,返回布尔值同时告诉TS类型判断结果 function isCityJSON(obj: unknown): obj is CityJSON { if (typeof obj !== 'object' || obj === null) return false; const candidate = obj as CityJSON; // 根据CityJSON规范添加所有必填字段的类型检查 return ( typeof candidate.type === 'string' && candidate.type === 'CityJSON' && typeof candidate.version === 'string' && typeof candidate.CityObjects === 'object' && candidate.CityObjects !== null ); }
然后修改数据处理流程,加入解析错误捕获和类型验证:
const cjsons = fetched .split('\n') .filter(line => line.trim().startsWith('{')) // 处理可能的空行或前后空格 .map(line => { try { return JSON.parse(line); } catch (err) { console.error('无效JSON行:', line); return null; } }) // 过滤掉解析失败或不符合类型的对象 .filter((obj): obj is CityJSON => obj !== null && isCityJSON(obj));
二、使用类型验证库(如Zod)
如果CityJSON结构复杂,手动写验证逻辑容易遗漏,可以用Zod这类库将TypeScript类型转换为运行时验证器:
- 先定义Zod Schema并推导TypeScript类型:
import { z } from 'zod'; // 严格按照CityJSON规范定义Schema const CityJSONSchema = z.object({ type: z.literal('CityJSON'), version: z.string(), CityObjects: z.record(z.object({ type: z.string(), // 这里可以继续定义CityObject的具体结构 })), // 添加其他必填/可选字段... }); // 从Schema推导TypeScript类型 type CityJSON = z.infer<typeof CityJSONSchema>;
- 处理数据时用
safeParse做验证:
const cjsons = fetched .split('\n') .filter(line => line.trim().startsWith('{')) .map(line => { try { const parsed = JSON.parse(line); const validation = CityJSONSchema.safeParse(parsed); if (validation.success) { return validation.data; } else { console.error('不符合CityJSON格式:', validation.error); return null; } } catch (err) { console.error('JSON解析失败:', line); return null; } }) .filter(obj => obj !== null) as CityJSON[]; // 此处断言安全,因为已通过验证
注意事项
- 直接用
as CityJSON[]属于强制类型断言,会跳过编译时检查且无运行时验证,一旦源数据不符合结构,后续操作极可能出现报错。 - 上述两种方法都能在运行时拦截无效数据,同时保留TypeScript的类型安全,还能输出错误日志便于排查问题。
内容的提问来源于stack exchange,提问作者pcace
相关产品推荐
相关产品推荐

