如何利用 JSON.parse 配合 reviver 实现对深拷贝副本原始属性的强类型校验

星晨小哥_5970

星晨小哥_5970

2026-05-06

954人浏览

原创

json.parse 的 reviver 无法实现强类型校验,因其仅处理 json 标准类型,丢失原型、函数、date 等信息,且 typescript 类型在运行时不存在;应改用解析后校验(如 zod)与显式重建。

如何利用 json.parse 配合 reviver 实现对深拷贝副本原始属性的强类型校验

JSON.parse 配合 reviver 无法实现真正意义上的“强类型校验”,因为它本质上只处理字符串到 JavaScript 值的解析,且会丢失原型、函数、undefined、Symbol、Date、RegExp 等非 JSON 可序列化类型。reviver 的作用是逐层转换已解析出的值,但它运行在 JSON 解析完成之后,此时原始结构已扁平化为纯数据对象,原始类型信息(如 class 构造器、TypeScript 类型注解)早已不可见。

为什么 reviver 不适合做强类型校验

reviver 函数接收的是 key 和 value,而 value 已是 JSON 解析后的结果(仅限 null、boolean、number、string、object、array)。它无法得知:

  • 该字段原本应是 Date 实例还是字符串时间戳
  • 某个 number 字段是否本应是枚举字面量(如 Status.Active)
  • 某个 object 是否应属于特定 class(如 User 类),因为 class 信息未进入 JSON 字符串
  • TypeScript 类型在运行时完全不存在,reviver 拿不到任何类型元数据

可行的替代方案:解析后校验 + 显式重建

若需保障深拷贝副本符合预期结构与类型约束,推荐分两步走:

  • 先安全解析:用 JSON.parse(..., reviver) 做基础清洗(如过滤敏感字段、转义字符串),但不依赖它做类型断言
  • 再显式校验与重建:使用类型守卫(type guard)、Zod、Yup 或自定义校验函数验证解析结果,并按需构造带原型/方法的对象

例如用 Zod 校验并保证类型:

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载
const userSchema = z.object({
  id: z.number().int().positive(),
  name: z.string().min(1),
  createdAt: z.string().datetime()
});

const raw = '{"id":123,"name":"Alice","createdAt":"2024-01-01T00:00:00Z"}';
const parsed = JSON.parse(raw);
const user = userSchema.parse(parsed); // 运行时校验,失败抛错
// user 是严格符合 schema 的对象,类型为 z.infer

若必须保留类实例,需额外序列化/反序列化逻辑

要让深拷贝副本具备原始类的方法和行为,不能只靠 JSON.parse。需要约定序列化格式(如添加 $$type 字段),并在 reviver 中识别并重建:

class User {
  constructor(public id: number, public name: string) {}
  greet() { return `Hello, ${this.name}`; }
  toJSON() {
    return { $$type: 'User', id: this.id, name: this.name };
  }
}

// 序列化时:
const json = JSON.stringify(new User(42, 'Bob')); // {"$$type":"User","id":42,"name":"Bob"}

// 反序列化时:
JSON.parse(json, (key, value) => {
  if (value?.['$$type'] === 'User') {
    return new User(value.id, value.name);
  }
  return value;
});

注意:这要求你完全控制序列化过程,并手动维护类型映射,不是通用强类型校验,而是有约定的类型重建。

小结:reviver 的定位是数据转换,不是类型系统

它适合做轻量清洗(如把字符串 'null' 转成 null、统一日期格式、剔除空字段),但不应承担类型安全职责。真正的强类型保障需结合:

  • 静态类型检查(TypeScript 编译期)
  • 运行时 Schema 校验(Zod/Yup/io-ts)
  • 必要时的手动类重建逻辑

把类型校验逻辑从 reviver 中解耦出来,代码更清晰、可测、可维护。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2155

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3322

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1116

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3799

7

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.31

3011

5

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

2025.10.31

554

9

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

2026.02.12

522

19

JavaScript中的typeof用法
JavaScript中的typeof用法

在JavaScript中,typeof是一个用来确定给定变量的数据类型的操作符。可以用来确定一个变量是字符串、数字、布尔值、函数、对象或undefined的数据类型。更多关于typeof用法相关文章,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

2023.11.23

8287

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21.1万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习