You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何获取JSON序列化反序列化后的对象类型?

实现JSONTypeOf<T>泛型以获取JSON序列化后的对象类型

要模拟JSON.stringify()转JSON再JSON.parse()解析后的对象类型,我们需要一个泛型来过滤掉不可序列化的属性(比如函数、Symbol),同时转换特殊类型(比如Date会变成ISO字符串)。以下是具体实现方案:

核心泛型实现

type JSONTypeOf<T> = 
  // Date对象会被序列化为ISO字符串
  T extends Date ? string :
  // BigInt无法被JSON序列化,直接标记为never(序列化会报错)
  T extends bigint ? never :
  // 数组中的函数、Symbol、undefined会被转为null
  T extends Function | symbol | undefined ? null :
  // 处理对象和数组的嵌套结构
  T extends object ?
    T extends Array<infer U> ? Array<JSONTypeOf<U>> :
    // 过滤对象中不可序列化的属性键,递归处理剩余属性值
    { [K in keyof T as T[K] extends Function | symbol | undefined ? never : K]: JSONTypeOf<T[K]> } :
  // 基础类型(string/number/boolean/null)保持原样
  T;

逻辑说明

  1. 特殊类型处理:
    • Date:JSON序列化后会变成ISO格式的字符串,所以直接映射为string类型。
    • bigint:JSON无法序列化BigInt,序列化时会抛出错误,因此标记为never。
  2. 不可序列化值处理:
    • 函数、Symbol、undefined在数组中会被JSON.stringify()转为null,所以映射为null类型。
    • 在对象中,这些属性会被直接忽略,因此通过映射类型过滤掉对应的键。
  3. 嵌套结构递归:
    • 数组:递归处理每个元素的类型。
    • 普通对象:过滤掉不可序列化属性后,递归处理剩余属性的值类型。

示例验证

用你提供的squirrel对象测试:

const squirrel = {
  name: "Töski",
  nuts: 392,
  consumeNut() {
    this.nuts -= 1;
  },
  birthDate: new Date(),
  favoriteSymbol: Symbol("nut"),
  maybeUndefined: undefined
};

// 获取序列化后的类型
type AfterJSONSquirrel = JSONTypeOf<typeof squirrel>;

最终AfterJSONSquirrel的类型为:

{
  name: string;
  nuts: number;
  birthDate: string;
}

再测试嵌套数组的情况:

const testArr = [() => {}, undefined, Symbol("test"), new Date(), 123];
type AfterJSONArr = JSONTypeOf<typeof testArr>;
// 类型为:(null | string | number)[]

内容的提问来源于stack exchange,提问作者Evan Summers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:16:01