Skip to content

Support type discrimination for nested sum types with integer and number variants #1586

@lanej

Description

@lanej

Problem

Currently, type-based discrimination is disabled for nested sum types that contain both integer and number variants (gen/schema_gen_sum.go:197-201):

if hasInteger && hasNumber && hasSumVariant {
    // TODO(tdakkota): Do not allow type discriminator for nested sum types with integer and
    // 	number variants at the same time. We can add support for this later, but it's not trivial.
    return false
}

This limitation means that schemas with nested oneOf/anyOf containing both integer and number types will fail type discrimination and fall back to other discrimination methods.

Example Scenario

oneOf:
  - type: integer
  - type: number
  - oneOf:  # nested sum type
      - type: string
      - type: boolean

This would be rejected for type discrimination even though the outer types (integer, number, nested-sum) are distinguishable.

Why This Limitation Exists

The challenge is that at JSON runtime level:

  • Both integer and number map to jx.Number
  • When a nested sum type also needs to discriminate between integer/number internally, the discrimination logic becomes complex
  • The current implementation doesn't handle the multi-level type checking required

Proposed Solution

To lift this limitation, we would need to:

  1. Enhanced type tracking: Track not just the outer JSON type but also the nested discrimination strategy
  2. Nested validation: When encountering jx.Number, check if the value is an integer (no decimal part) vs float
  3. Cascading discrimination: If outer type matches, cascade to inner sum type's discrimination logic

Implementation Complexity

This is marked as "not trivial" because:

  • Requires runtime integer vs float detection (value == math.Floor(value) or similar)
  • Template generation becomes more complex (nested switches)
  • Need to handle validation errors at multiple levels
  • Performance implications of additional type checking

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions