Closed cmcnicholas closed 4 months ago
@cmcnicholas Hi,
Unfortunately, structuredClone
won't clone the Symbol
properties TypeBox uses to compose, compile and check types. However you can use TypeBox's CloneType
function to perform a deep clone of a type.
import { Type, CloneType } from "@sinclair/typebox"; // added
import { TypeCompiler } from "@sinclair/typebox/compiler";
// database model
const LettersDbModel = Type.Any([Type.Literal("A"), Type.Literal("B")]);
// a web model we want to expose, derived from db model (in this case they are identical)
const LettersWebModel = CloneType(LettersDbModel);
// const LettersWebModel = { ...LettersDbModel }; // this works?
console.log(LettersWebModel)
// a web model we want to expose
const SomeWebModel = Type.Object({
letter: LettersWebModel,
});
// UPDATE: This line should succeed as the compositing symbols are preserved
const SomeWebModelCompiled = TypeCompiler.Compile(SomeWebModel);
console.log(
"should be false",
SomeWebModelCompiled.Check({
letter: "C",
})
);
console.log(
"should be true",
SomeWebModelCompiled.Check({
letter: "B",
})
);
Also as an aside, it looks like the LettersDbModel
may be incorrect...
const LettersDbModel = Type.Any([Type.Literal("A"), Type.Literal("B")]);
// did you mean?
const LettersDbModel = Type.Union([Type.Literal("A"), Type.Literal("B")]); ??
Hope this helps S
@cmcnicholas Hi,
Unfortunately,
structuredClone
won't clone theSymbol
properties TypeBox uses to compose, compile and check types. However you can use TypeBox'sCloneType
function to perform a deep clone of a type.import { Type, CloneType } from "@sinclair/typebox"; // added import { TypeCompiler } from "@sinclair/typebox/compiler"; // database model const LettersDbModel = Type.Any([Type.Literal("A"), Type.Literal("B")]); // a web model we want to expose, derived from db model (in this case they are identical) const LettersWebModel = CloneType(LettersDbModel); // const LettersWebModel = { ...LettersDbModel }; // this works? console.log(LettersWebModel) // a web model we want to expose const SomeWebModel = Type.Object({ letter: LettersWebModel, }); // UPDATE: This line should succeed as the compositing symbols are preserved const SomeWebModelCompiled = TypeCompiler.Compile(SomeWebModel); console.log( "should be false", SomeWebModelCompiled.Check({ letter: "C", }) ); console.log( "should be true", SomeWebModelCompiled.Check({ letter: "B", }) );
Also as an aside, it looks like the
LettersDbModel
may be incorrect...const LettersDbModel = Type.Any([Type.Literal("A"), Type.Literal("B")]); // did you mean? const LettersDbModel = Type.Union([Type.Literal("A"), Type.Literal("B")]); ??
Hope this helps S
I did thanks, my code is using it correctly was just my repro was rubbish :P
CloneType
absolutely works for me 👍
When using
structuredClone
on typebox models I experience "Preflight validation check failed to guard for the given schema".This does not happen when simply destructuring a typbox model. e.g.
My use case is I want to reuse model definitions, potentially enhancing or changing properties as such
$id
etc. without risk of referencing the originating object. I know destructuring should work butstructuredClone
feels like a neater solution to make sure changes are isolated.