Skip to content

Conversation

baweaver
Copy link

@baweaver baweaver commented Sep 27, 2025

Add support for intersection types in schema definitions

Fixes #494

Problem

Dry-schema was failing when using intersection types (created with & operator) in schema definitions, throwing NoMethodError: undefined method 'visit_intersection'.

Root Cause

The PredicateInferrer::Compiler and PrimitiveInferrer::Compiler classes didn't have methods to handle
intersection type AST nodes, and the DSL wasn't processing intersection types like it does for sum types.

Chances are that parts of this change should move upstream to Dry::Types.

Solution

• Added visit_intersection methods to both compiler classes to handle intersection type inference
• Extended extract_type_spec to process intersection types with AND logic (similar to how sum types use OR logic)
• Intersection types now properly validate that ALL constituent types must pass

Changes

lib/dry/schema/predicate_inferrer.rb: Add visit_intersection method
lib/dry/schema/primitive_inferrer.rb: Add visit_intersection method
lib/dry/schema/macros/dsl.rb: Handle intersection types in extract_type_spec
spec/integration/schema/intersection_types_spec.rb: Comprehensive test coverage
CHANGELOG.md: Document the fix

Testing

• Validates the exact example from the issue works correctly
• Tests intersection with sum types (complex algebraic data types)
• Tests DSL integration with predicate rules
• Tests proper validation logic (AND semantics)

Example Usage

# Now works without errors
intersection_type =
  Types::Hash.schema(a: Types::String) & 
  (Types::Hash.schema(b: Types::String) | Types::Hash.schema(c: Types::String))

schema = Dry::Schema.Params do
  required(:body).value(intersection_type)
end

schema.call(body: {a: "test", b: "value"}) # passes
schema.call(body: {b: "value"})            # fails - missing 'a'

- Add visit_intersection methods to PredicateInferrer::Compiler and PrimitiveInferrer::Compiler
- Handle intersection types in extract_type_spec with AND logic (similar to sum types with OR logic)
- Add comprehensive tests for intersection types including DSL usage
- Update CHANGELOG.md

Fixes dry-rb#494
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dry schema fails on some algebraic data types
1 participant