引言:JSON 与 TypeScript — 数据处理的理想搭档
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,已成为客户端与服务器交互、配置存储以及结构化信息传输的事实标准。TypeScript 作为 JavaScript 的严格类型化超集,为安全、可预测地处理 JSON 提供了强大工具。在本文中,我们将通过实战讲解如何在 TypeScript 中正确解析(将 JSON 字符串转换为对象)和序列化(将对象转换为 JSON 字符串)数据,避免常见错误,并充分利用类型系统的优势。
基础:TypeScript 中的 JSON.parse() 与 JSON.stringify()
TypeScript 完全继承了 JavaScript 内置的 JSON 处理方法:JSON.parse() 和 JSON.stringify()。然而,在严格类型化的环境中使用它们需要特殊的方法。
JSON.parse() — 从字符串到对象
JSON.parse() 方法接收一个 JSON 字符串并返回一个对象。在 TypeScript 中,默认返回类型为 any,这让我们失去了类型化的所有优势。来看一个例子:
const jsonString = '{"name": "TypeScript", "version": 5.3}';const parsed: any = JSON.parse(jsonString);console.log(parsed.name); // 可以工作,但没有自动补全和类型检查要获得类型化的结果,请使用类型断言:
interface Language { name: string; version: number;}
const jsonString = '{"name": "TypeScript", "version": 5.3}';const parsed = JSON.parse(jsonString) as Language;console.log(parsed.name.toUpperCase()); // 自动补全生效!JSON.stringify() — 从对象到字符串
JSON.stringify() 将对象序列化为 JSON 字符串。TypeScript 会检查传入的对象是否可有效序列化(不包含函数、undefined、Symbol 等)。
interface User { id: number; name: string; isActive: boolean;}
const user: User = { id: 1, name: "Alice", isActive: true };const jsonString = JSON.stringify(user);console.log(jsonString); // '{"id":1,"name":"Alice","isActive":true}'进阶技巧:类型化与错误处理
在实际应用中,JSON 处理很少是完美的。数据可能以意外格式从服务器传来,包含多余字段或缺少必填字段。让我们看看 TypeScript 如何帮助应对这些问题。
创建通用安全解析函数
编写一个通用函数,接收 JSON 字符串并返回带错误处理的类型化结果:
function safeParse<T>(json: string): T | null { try { return JSON.parse(json) as T; } catch (error) { console.error("JSON 解析错误:", error); return null; }}
// 使用示例interface Product { id: number; title: string; price: number;}
const rawData = '{"id": 101, "title": "Laptop", "price": 999.99}';const product = safeParse<Product>(rawData);if (product) { console.log(product.title); // "Laptop"}使用自定义类型守卫进行数据验证
即使使用了类型断言 as T,TypeScript 也不会检查数据是否真正符合接口。要运行时验证,请使用类型守卫:
function isProduct(obj: any): obj is Product { return ( typeof obj === 'object' && obj !== null && typeof obj.id === 'number' && typeof obj.title === 'string' && typeof obj.price === 'number' );}
const rawData = '{"id": "abc", "title": "Phone", "price": 599}';const parsed = JSON.parse(rawData);if (isProd