API Stability Notice

Macroforge is under active development. The API is not yet stable and may change between versions. Some documentation sections may be outdated.

Serde Reference

@derive(Serialize) and @derive(Deserialize) generate JSON serialization with cycle detection, forward references, and runtime validation. This section is the complete reference; the Serialize and Deserialize pages cover the basics.

Generated API

For a class, the macros emit static methods plus standalone functions that the statics delegate to:

/** @derive(Serialize, Deserialize) */
class User {
  name: string;
  email: string;
}

// Serialize
User.serialize(user);                 // string
User.serialize(user, true);           // keep __type/__id metadata
User.serializeWithContext(user, ctx); // Record<string, unknown>

// Deserialize
const r = User.deserialize(input);
if (r.success) {
  r.value;   // User
} else {
  r.errors;  // Array<{ field: string; message: string }>
}

User.deserialize(input, { freeze: true }); // freeze all deserialized objects
User.hasShape(obj);       // boolean — required keys present
User.is(value);           // type guard
User.validateField("email", value);
User.validateFields({ email: "…" });

Static wrappers vs standalone functions

This distinction trips people up, so it’s worth stating plainly:

DeclarationWhat you get
Classstatic X(...) and standalone {camel}X(...)
Interfacestandalone {camel}X(...) only
Type aliasstandalone {camel}X(...) only
Enumstandalone {camel}X(...) only

There is no class to attach statics to for the last three, so they get functions like userSerialize(value) and userDeserialize(input). With generateConvenienceConst enabled (the default), a grouping const — or, for enums, a merged namespace — is also emitted so you can still write User.serialize(...).

Enums differ

Enum deserialize throws on invalid input rather than returning the success/errors union. Enum serialize takes no keepMetadata parameter.

Metadata and keepMetadata

serialize adds __type and __id fields internally to support cycle detection, then strips them from the JSON output unless you pass keepMetadata: true. If you’re round-tripping a cyclic graph, keep the metadata; if you’re producing an API payload, leave it off.

Section contents