Skip to content

Conversation

@gcanti
Copy link
Contributor

@gcanti gcanti commented Dec 18, 2025

This example shows how Schema.toCodecJson and Schema.toJsonSchema can describe the same JSON shape for a custom type.

Headers is not JSON-friendly by default. JSON.stringify(new Headers({ a: "b" })) produces {} because the header data is not stored in enumerable properties. By adding a toCodecJson annotation, you define a JSON-safe representation and use it for both serialization and JSON Schema generation.

Example (Align a JSON serializer and JSON Schema for Headers)

import { Schema, SchemaGetter } from "effect"

const data = new Headers({ a: "b" })

// `Headers` does not serialize to JSON in a useful way by default.
console.log(JSON.stringify(data))
// {}

// Define a schema with a `toCodecJson` annotation.
// The JSON form will be: [ [name, value], ... ].
const MyHeaders = Schema.instanceOf(Headers, {
  toCodecJson: () =>
    Schema.link<Headers>()(
      // JSON-safe representation: array of [key, value] pairs
      Schema.Array(Schema.Tuple([Schema.String, Schema.String])),
      {
        decode: SchemaGetter.transform((headers) => new Headers(headers.map(([key, value]) => [key, value]))),
        encode: SchemaGetter.transform((headers) => [...headers.entries()])
      }
    )
})

const schema = Schema.Struct({
  headers: MyHeaders
})

// Build a serializer that produces JSON-safe values using the `toCodecJson` annotation.
const serializer = Schema.toCodecJson(schema)

const json = Schema.encodeUnknownSync(serializer)({
  headers: data
})

// The JSON-encoded value:
console.log(json)
// { headers: [ [ 'a', 'b' ] ] }

// Generate a JSON Schema that matches the JSON-safe shape produced by the serializer.
const document = Schema.toJsonSchemaDocument(schema)

console.log(JSON.stringify(document.schema, null, 2))
/*
{
  "type": "object",
  "properties": {
    "headers": {
      "type": "array",
      "items": {
        "type": "array",
        "prefixItems": [
          {
            "type": "string"
          },
          {
            "type": "string"
          }
        ],
        "maxItems": 2,
        "minItems": 2
      }
    }
  },
  "required": [
    "headers"
  ],
  "additionalProperties": false
}
*/

// Example (Decode a JSON-safe value using the same serializer)
// If a value matches the JSON Schema above, you can decode it with the serializer.
console.log(String(Schema.decodeUnknownExit(serializer)(json)))
// Success({"headers":Headers([["a","b"]])})

@gcanti gcanti marked this pull request as draft December 18, 2025 18:47
@gcanti gcanti force-pushed the remove-ToJsonSchema-Declaration branch from 090342b to 212c0ff Compare December 24, 2025 08:38
@gcanti gcanti force-pushed the remove-ToJsonSchema-Declaration branch from 110acaa to c80ff97 Compare December 26, 2025 07:40
@gcanti gcanti force-pushed the remove-ToJsonSchema-Declaration branch from 2ae69c1 to 92e8c4f Compare December 27, 2025 05:44
@gcanti gcanti marked this pull request as ready for review December 28, 2025 08:20
@gcanti gcanti merged commit 5ae8545 into main Dec 28, 2025
13 checks passed
@gcanti gcanti deleted the remove-ToJsonSchema-Declaration branch December 28, 2025 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants