Skip to content

[v1] decode not get called when inside Type.Record #1495

@hanayashiki

Description

@hanayashiki

Hi, I love this geeky runtime library, but I am encountered with mysteriously skipped decode callback:

This is a minimal repro:

/**
 * Typebox Bug: Type.Decode transform not called for Union members inside Type.Record
 */
import Type from "typebox";
import { Value } from "typebox/value";

// Storage for decode tracking
const decodeCalledFor = new Set<object>();

// Schema with decode transform
const MyType = Type.Decode(
  Type.Object({
    name: Type.String(),
  }),
  (value) => {
    decodeCalledFor.add(value);
    return value;
  }
);

const OtherType = Type.Object({
  $ref: Type.String(),
});

// Test 1: Direct decode - WORKS
console.log("=== Test 1: Direct decode ===");
const directData = { name: "test" };
const directResult = Value.Decode(MyType, directData);
console.log("Decode called:", decodeCalledFor.has(directResult)); // true

// Test 2: Union decode - WORKS
console.log("\n=== Test 2: Union decode ===");
decodeCalledFor.clear();
const unionSchema = Type.Union([MyType, OtherType]);
const unionData = { name: "test" };
const unionResult = Value.Decode(unionSchema, unionData);
console.log("Decode called:", decodeCalledFor.has(unionResult)); // true

// Test 3: Record with Union - BUG: decode NOT called
console.log("\n=== Test 3: Record + Union decode ===");
decodeCalledFor.clear();
const recordSchema = Type.Record(Type.String(), Type.Union([MyType, OtherType]));
const recordData = { item1: { name: "test" } };
const recordResult = Value.Decode(recordSchema, recordData);
console.log("Decode called:", decodeCalledFor.has(recordResult.item1)); // false - BUG!

// Test 4: Record without Union - also NOT called (confirms Record is the issue)
console.log("\n=== Test 4: Record without Union ===");
decodeCalledFor.clear();
const recordOnlySchema = Type.Record(Type.String(), MyType);
const recordOnlyData = { item1: { name: "test" } };
const recordOnlyResult = Value.Decode(recordOnlySchema, recordOnlyData);
console.log("Decode called:", decodeCalledFor.has(recordOnlyResult.item1)); // false - BUG!

console.log("\n=== Summary ===");
console.log("Type.Decode transform is NOT called for values inside Type.Record");

The test result:

=== Test 1: Direct decode ===
Decode called: true

=== Test 2: Union decode ===
Decode called: true

=== Test 3: Record + Union decode ===
Decode called: false

=== Test 4: Record without Union ===
Decode called: false

=== Summary ===
Type.Decode transform is NOT called for values inside Type.Record

Version:

"typebox": "^1.0.69"

Global Settings: default

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions