Hi Haydn — as per our discussion over email, I'm opening this issue here for further conversation. Thank you for taking the time to explain the design rationale, really appreciate it.
Behavior
Type.Partial() silently discards TransformKind when applied to a schema with outer Type.Transform(). Same for Type.Pick(), Type.Omit(), and Type.Composite().
I understand that interior Transform (applied to individual properties like Type.Transform(Type.String())) is retained through Partial — this is great. The issue is specifically about outer/structural Transform.
import { Type, TransformKind } from "@sinclair/typebox";
import { Value } from "@sinclair/typebox/value";
const Schema = Type.Transform(
Type.Object({ bio: Type.String() })
)
.Decode(v => ({ bio: v.bio.replace(/<[^>]*>/g, "") }))
.Encode(v => v);
console.log(TransformKind in Schema); // true
console.log(TransformKind in Type.Partial(Schema)); // false — silent discard
Value.Decode(Schema, { bio: "<b>hi</b>" });
// => { bio: "hi" } — Transform active
Value.Decode(Type.Partial(Schema), { bio: "<b>hi</b>" });
// => { bio: "<b>hi</b>" } — Transform silently gone
I also checked typebox 1.x — Partial() discards ~codec the same way.
Question
Type.Intersect() already throws when it encounters Transform (as of 0.34.48). Would it make sense for Partial/Pick/Omit to do the same? A throw would:
- Make the behavior visible (no silent surprise)
- Be consistent with Intersect's approach
- Guide users toward the interior-Transform pattern you recommended
Best Regards,
YD
Hi Haydn — as per our discussion over email, I'm opening this issue here for further conversation. Thank you for taking the time to explain the design rationale, really appreciate it.
Behavior
Type.Partial()silently discardsTransformKindwhen applied to a schema with outerType.Transform(). Same forType.Pick(),Type.Omit(), andType.Composite().I understand that interior Transform (applied to individual properties like
Type.Transform(Type.String())) is retained through Partial — this is great. The issue is specifically about outer/structural Transform.I also checked
typebox1.x —Partial()discards~codecthe same way.Question
Type.Intersect()already throws when it encounters Transform (as of 0.34.48). Would it make sense for Partial/Pick/Omit to do the same? A throw would:Best Regards,
YD