-
Notifications
You must be signed in to change notification settings - Fork 186
Closed
Description
When using Value.Cast
with a schema defined using Type.Intersect
, nested object properties are not correctly coerced if the input contains a partial object. The casting will use the default values even when some values are provided.
Minimal reproduction
const schema = Type.Intersect([
Type.Object({}),
Type.Object({
name: Type.String(),
age: Type.Optional(Type.Number()),
location: Type.Object({
lat: Type.Number(),
long: Type.Number(),
}),
greeting: Type.String(),
}),
])
const result = coerceValue(schema, { location: {}, greeting: 'Hello' })
// ❌ Actual output:
{
greeting: '',
location: { lat: 0, long: 0 },
name: ''
}
// ✅ Expected output:
{
greeting: 'Hello',
location: { lat: 0, long: 0 },
name: ''
}
console.log(result)
✅ Notes:
- If the location field is removed, the result is correct:
const result2 = coerceValue(schema, { greeting: 'Hello' })
// Output: { greeting: 'Hello', location: { lat: 0, long: 0 }, name: '' }
- Replacing
Type.Intersect
withType.Composite
resolves the casting issue:
const schema = Type.Composite([...])
const result = coerceValue(schema, { location: {}, greeting: 'Hello' })
// Output: { greeting: 'Hello', location: { lat: 0, long: 0 }, name: '' }
⚠️ Problem with Type.Composite:
The return type is no longer correct when using features like Type.TemplateLiteral
with Type.Record
. For example:
const schema = Type.Composite([
Type.Record(Type.TemplateLiteral('x-${string}'), Type.Unknown()),
Type.Object({
name: Type.String(),
...
})
])
type t = Static<typeof schema> // Incorrect type inference
✅ Type inference works correctly when using Type.Intersect
.
Metadata
Metadata
Assignees
Labels
No labels