Codables – 受 Swift 启发,声明式的 JSON 序列化
Codables – Swift-inspired, declarative JSON serialization

原始链接: https://github.com/pie6k/codables

## CodableJSON:一款快速且声明式的JSON序列化库 CodableJSON是一个TypeScript/JavaScript库,提供了一种新的JSON序列化方法。 您可以使用现代装饰器(`@codableClass`、`@codable`)来标记类和属性为可序列化,而无需编写自定义编码/解码函数。 它可替代SuperJSON,具有**3倍的性能**,同时保持**与框架无关**和**安全**(防止原型污染)。 CodableJSON是**完全类型安全的**,支持TypeScript,并且**没有依赖项**——压缩后保持在10KB以下。 主要特性包括: * **声明式序列化:** 通过装饰器简化数据处理。 * **SuperJSON替代品:** 更快的编码/解码。 * **全面的类型支持:** 开箱即用地处理日期、映射、集合等。 * **自定义类型支持:** 允许定义和编码自定义类型。 * **深度克隆:** 保持类型和引用。 使用npm/yarn/pnpm安装,并查阅详细文档以获取高级定制选项。

## Codables:Swift 声明式 JSON 序列化 开发者 pie6k 发布了 Codables,这是一个新的 Swift JSON 序列化库,旨在解决现有解决方案(如 SuperJSON)遇到的复杂问题。虽然 pie6k 认可 SuperJSON 的优势,但他发现对于深度嵌套、复杂的数据模型,维护独立的序列化格式和 TypeScript 格式非常繁琐。 Codables 旨在通过使用现代装饰器(decorators)的声明式方法简化此过程,从而显著减少样板代码。该库允许开发者直接在模型类中定义数据的序列化和反序列化方式。 提供了一个交互式游乐场用于测试 ([https://codableslib.com/playground](https://codableslib.com/playground)),源代码可以在 GitHub 上找到 ([https://github.com/pie6k/codables](https://github.com/pie6k/codables))。开发者欢迎对新库的反馈。
相关文章

原文

npm npm bundle size TypeScript License

CodableJSON is a declarative JSON serialization library that aims to enable a whole new paradigm of data serialization in TypeScript/JavaScript.

Using modern decorators (@codableClass and @codable), you can mark your data model classes as serializable instead of writing custom (to/from) JSON functions.

Besides that, it's 3x faster SuperJSON alternative.

  • Declarative and extensible: Mark props and classes as serializable instead of writing custom (to/from) JSON functions.
  • SuperJSON drop-in replacement: ~3x faster than SuperJSON (see benchmark)
  • Type-safe: Full TypeScript support with autocompletion and type inference
  • Zero dependencies: Fully standalone, no external dependencies. Less than 10KB gziped.
  • Well tested: Every feature is covered by tests. It passes most of SuperJSON tests moved into CodableJSON (including plenty of edge cases)
  • Framework agnostic: Works with any JavaScript/TypeScript project
  • Secure: Built-in protection against prototype pollution
npm install codablejson
yarn add codablejson
pnpm add codablejson

Besides declarative framework (described below), it is also an ultra-fast SuperJSON alternative that can encode/decode almost any JavaScript input.

import { encode, decode } from "codablejson";

const data = {
  date: new Date("2025-01-01"),
  map: new Map([["key", "value"]]),
};

const encoded = encode(data);
// {
//   date: { $$Date: "2025-01-01T00:00:00.000Z" },
//   map: { $$Map: [["key", "value"]] },
// }

const decoded = decode(encoded); // fully equals to the original data

2. Declarative Class Serialization

Instead of writing custom (to/from) JSON functions, you can mark your classes and properties as serializable with modern decorators.

Let's define some classes and mark them as serializable:

import { codableClass, codable, Coder } from "codablejson";

@codableClass("Player")
class Player {
  @codable() name: string;
  @codable() score: number;

  // Note: constructor is not needed for CodableJSON to work, it is here for convenience of creating instances.
  constructor(data: Pick<Player, "name" | "score">) {
    this.name = data.name;
    this.score = data.score;
  }
}

@codableClass("GameState")
class GameState {
  @codable() players: Set<Player> = new Set();
  @codable() createdAt = new Date();
  @codable() activePlayer: Player | null = null;

  addPlayer(player: Player) {
    this.players.add(player);
    this.activePlayer = player;
  }
}

// Use your classes naturally
const gameState = new GameState();
gameState.addPlayer(new Player({ name: "Alice", score: 100 }));

Now, let's create a custom coder instance that is aware of our classes:

const coder = new Coder([GameState]);

Now, we can serialize our game state:

const encoded = coder.encode(gameState);

Will be serialized as:

{
  "$$GameState": [
    {
      "players": {
        "$$Set": [
          {
            "$$Player": [
              {
                "$$id": 0,
                "name": "Foo",
                "score": 100
              }
            ]
          }
        ]
      },
      "createdAt": { "$$Date": "2025-11-27T23:00:00.000Z" },
      "activePlayer": { "$$ref": 0 }
    }
  ]
}

We can decode it back to our original data. All types, references, and circular dependencies are preserved!

const decoded = coder.decode<GameState>(encoded);

Note

Note: for classes to be automatically serialized, some conventions need to be followed. Read more about it here.

Out of the box, CodableJSON handles most of the built-in JavaScript types:

Date, BigInt, Set, Map, RegExp, Symbol, URL, URLSearchParams, Error, undefined, typed arrays, special numbers like NaN, Infinity, -Infinity, -0 (treated as null by regular JSON).

Read more about supported types →

CodableJSON is heavily optimized for performance:

  • Encoding: ~3-3.5x faster than SuperJSON across all data sizes and types
  • Decoding: Comparable to or faster than SuperJSON depending on the data type

View detailed benchmarks →

import { encode, decode, stringify, parse, clone } from "codablejson";

// Basic encoding/decoding
const encoded = encode(data);
const decoded = decode(encoded);

// With JSON stringification
const jsonString = stringify(data);
const restored = parse(jsonString);

// Deep clone maintaining all types and references equality
const foo = { foo: "foo" };
const original = [foo, foo];
const cloned = clone(original);
// cloned === original; // false
// cloned[0] === original[0]; // false -> nested clone
// cloned[0] === cloned[1]; // true -> reference equality is preserved

Declarative Class Serialization

import { codableClass, codable, Coder } from "codablejson";

@codableClass("MyClass")
class MyClass {
  @codable() property: string;
}

const coder = new Coder([MyClass]);
const encoded = coder.encode(instance);
const decoded = coder.decode<MyClass>(encoded);

Read more about custom types →

You can also use lower-level API to create custom types and encode/decode them manually.

import { codableType, Coder } from "codablejson";

const $$custom = codableType(
  "CustomType", // name of the type
  (value) => value instanceof CustomType, // how to detect some value should be encoded using this type
  (instance) => instance.data, // how to encode the value (might return rich data like `Map` or `Set`, or even other custom types)
  (data) => new CustomType(data), // how to recreate the value from the encoded data
);

const coder = new Coder([$$custom]);
// or
const coder = new Coder();
coder.register($$custom);

MIT

联系我们 contact @ memedata.com