Loosen z.strictObject() inside intersection#5587
Conversation
z.strictObject() inside intersection
There was a problem hiding this comment.
Pull request overview
This PR modifies the intersection logic for Zod schemas to loosen the behavior when strict objects are intersected. Instead of reporting all unrecognized keys from either side, the new logic only reports keys that are unrecognized by BOTH sides of the intersection. This allows keys recognized by either schema to pass validation.
Key changes:
- Updated
handleIntersectionResultsto track which side reports each key as unrecognized - Modified logic to only create an error for keys rejected by both schemas
- Added tests demonstrating the new behavior for strict+strip and strict+strict intersections
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/zod/src/v4/core/schemas.ts | Implements new intersection logic that filters unrecognized_keys issues to only report keys unrecognized by both sides |
| packages/zod/src/v4/classic/tests/intersection.test.ts | Updates existing test and adds new tests to validate the loosened strict object intersection behavior |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
This change loosens strictObject behavior in intersections by only rejecting keys that both sides don't recognize. The approach is sound and the implementation is correct. The tests clearly demonstrate the intended behavior for strict+strip and strict+strict cases.

Previously strict objects were functionality incompatible with intersections, as the inner strict object would throw on any unrecognized key. Now, this is loosened inside of intersections. Any key recognized by at least one side of the intersection will now pass validation:
When both sides are strict, keys unrecognized by both sides will still error: