如何实现类型安全的JSON解析函数?类型不符时返回默认值
解决safeJSONParse类型校验问题
TypeScript的泛型是编译时特性,运行时会被完全擦除,所以你原函数里的as T只是编译时的类型断言,根本无法在运行时验证解析结果是否真的符合泛型T的结构。要实现「类型不符时返回默认值」的需求,必须手动添加运行时类型校验逻辑。
解决方案:添加类型守卫参数
给函数传入一个「类型守卫(Type Guard)」函数,用来在运行时判断解析后的对象是否符合目标类型T。修改后的函数如下:
// 定义类型守卫的通用类型 type TypeGuard<T> = (value: unknown) => value is T; const safeJSONParse = <T>(json: string, defaultValue: T, typeGuard: TypeGuard<T>): T => { try { const parsedValue = JSON.parse(json); // 用类型守卫校验结构,符合则返回解析值,否则返回默认值 return typeGuard(parsedValue) ? parsedValue : defaultValue; } catch (error) { // 解析失败直接返回默认值 return defaultValue; } };
使用示例
以一个User类型为例,先编写对应的运行时校验逻辑,再调用函数:
// 目标类型 interface User { id: number; name: string; } // 运行时类型守卫:验证对象是否符合User结构 const isUser = (value: unknown): value is User => { return ( typeof value === 'object' && value !== null && 'id' in value && typeof (value as User).id === 'number' && 'name' in value && typeof (value as User).name === 'string' ); }; // 测试不同场景 const validUserJson = '{"id": 1, "name": "Alice"}'; const wrongTypeJson = '{"id": "123", "name": "Bob"}'; // id是字符串,不符合User const invalidJson = '{invalid-json}'; console.log(safeJSONParse(validUserJson, { id: 0, name: '默认用户' }, isUser)); // 输出:{ id: 1, name: 'Alice' } console.log(safeJSONParse(wrongTypeJson, { id: 0, name: '默认用户' }, isUser)); // 输出:{ id: 0, name: '默认用户' } console.log(safeJSONParse(invalidJson, { id: 0, name: '默认用户' }, isUser)); // 输出:{ id: 0, name: '默认用户' }
补充说明
- 如果不想手动编写类型守卫,可以用
zod、io-ts这类库自动生成运行时校验器,减少重复代码; - 修改后的函数返回类型统一为
T,比原函数的T | unknown更严谨,因为无论解析成功与否,最终返回的都是符合T类型的值(要么是校验通过的解析结果,要么是默认值)。
内容的提问来源于stack exchange,提问作者GRZa
相关产品推荐
相关产品推荐

