TypeScript中的JSON处理:从基本操作到高级类型化
JSON(JavaScript Object Notation)仍然是Web开发中主要的数据交换格式。TypeScript作为JavaScript的严格类型化超集,提供了强大且安全的工具来高效处理JSON。在本文中,我们将深入探讨TypeScript中JSON处理的各个方面:从简单的解析到使用泛型和第三方库的复杂验证。
1. 基本操作:解析与序列化
TypeScript完全继承了JavaScript中用于处理JSON的内置方法:JSON.parse() 和 JSON.stringify()。然而,在TypeScript中使用它们需要特别注意类型。
解析JSON字符串
// 简单解析——结果为any类型
const rawData = JSON.parse('{"name": "Alice", "age": 30}');
// rawData的类型为any——失去了TypeScript的所有优势
// 正确方法:通过泛型指定期望的类型
interface User {
name: string;
age: number;
}
const user: User = JSON.parse('{"name": "Alice", "age": 30}');
// user现在已类型化,但TypeScript不会在运行时检查其符合性
重要提示: JSON.parse() 不会检查传入的字符串是否符合指定的接口。这可能导致运行时错误。为了可靠的验证,请使用额外的工具。
将对象序列化为JSON
const user: User = { name: "Bob", age: 25 };
const jsonString = JSON.stringify(user);
// 结果:'{"name":"Bob","age":25}'
// 使用replacer进行自定义序列化
const filteredJson = JSON.stringify(user, ['name']);
// 结果:'{"name":"Bob"}'
// 带缩进的格式化
const prettyJson = JSON.stringify(user, null, 2);
/* 结果:
{
"name": "Bob",
"age": 25
}
*/
2. JSON数据的类型化:接口与类型
正确的类型化是TypeScript在处理JSON时的关键优势。让我们看看主要方法。
数据结构的接口
interface ApiResponse<T> {
status: 'success' | 'error';
data: T;
message?: string;
timestamp: number;
}
interface Product {
id: string;
title: string;
price: number;
tags: string[];
inStock: boolean;
}
// 使用泛型对API响应进行类型化
type ProductResponse = ApiResponse<Product>;
const response: ProductResponse = {
status: 'success',
data: {
id: 'prod-123',
title: 'Wireless Mouse',
price: 29.99,
tags: ['electronics', 'accessories'],
inStock: true
},
timestamp: Date.now()
};
动态JSON结构的类型
// 对于键未知的对象
type DynamicObject = Record<string, unknown>;
// 对于严格类型化的字典
interface Config {
[key: string]: string | number | boolean;
}
// 用于多态JSON的联合类型
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'rectangle'; width: number; height: number }
| { kind: 'triangle'; base: number; height: number };
function calculateArea(shape: Shape): number {
switch (shape.kind) {
case 'circle': return Math.PI * shape.radius ** 2;
case 'rectangle': return shape.width * shape.height;
case 'triangle': return (shape.base * shape.height) / 2;
}
}
3. JSON数据的验证:运行时检查
TypeScript仅在编译阶段检查类型。对于JSON数据(例如来自外部API)的运行时验证,请使用专门的库。
使用Zoo进行声明式验证
import { z } from 'zod';
// 定义模式
const UserSchema = z.object({
name: z.string().min(2).max(50),
age: z.number().int().positive().max(120),
email: z