sinclairzx81 / typebox

Json Schema Type Builder with Static Type Resolution for TypeScript
Other
4.65k stars 150 forks source link

Value.Clean causes dereference error on Recursive type with nullable optional union #845

Closed truumahn closed 3 months ago

truumahn commented 3 months ago

Here's a repro with vitest:

import { Type, type StaticDecode, type TSchema } from "@sinclair/typebox";
import { test } from "vitest";
import { Value } from "@sinclair/typebox/value";

export function Parse<T extends TSchema, R = StaticDecode<T>>(
  schema: T,
  value: unknown
): R {
  const cloned = Value.Clone(value);
  const cleaned = Value.Clean(schema, cloned);
  return Value.Decode(schema, cleaned);
}

const RecursiveSchema = Type.Recursive((This) => {
  return Type.Object({
    id: Type.Number(),
    parent: Type.Optional(Type.Union([This, Type.Null()])),
  });
});

const inputs = [
  {
    id: 1,
    parent: {
      id: 2,
      parent: {
        id: 3,
      },
    },
  },
];

test("schema parses", () => {
  for (const input of inputs) {
    Parse(RecursiveSchema, input);
  }
});

If I remove the union from parent to be like this: Type.Optional(This), then there's no trouble.

sinclairzx81 commented 3 months ago

@truumahn Hi, thanks for reporting. This is definitely a bug!

I have pushed a version on 0.32.23 where this issue should be resolved. Relevant PR is here https://github.com/sinclairzx81/typebox/pull/847

If you just want to test things your side, can close off this issue Thanks again! S

truumahn commented 3 months ago

Thank you, works perfectly!