Skip to content

Union types are ignored by validation #941

Closed
@pluma

Description

@pluma

✏️ Describe the bug

Given a Data class with a constructor like this:

__construct(
  public string $id,
  public SomeData|OtherData $thing
) {}

I would expect the validation to first try to validate the parameter $thing using SomeData, then fall back to OtherData and for the first matching type to be used for this property when using ::from($jsonString).

But instead the validator will generate rules for $thing based on the type information of SomeData and only that information because it prioritizes having a fully denormalized list of rules even if it means discarding the alternatives.

There does seem to be actual logic around UnionType in this library but the validator doesn't support it for validation and everything else seems to run downstream from that.

↪️ To Reproduce

it('cannot validate union types', function () {
    class ExampleData extends Data
    {
        public function __construct(
          public string $id,
          public SomeData|OtherData $thing
        ) {
        }
    }

    class SomeData extends Data
    {
        public function __construct(
            #[In('SomeThing')]
            public string|Optional $type,
            public string $taste
        ) {
        }
    }

    class OtherData extends Data
    {
        public function __construct(
            #[In('OtherThing')]
            public string $type,
            public int $size
        ) {
        }
    }

    dd(BaseData::validateAndCreate(['id' => 'abc', 'thing' => ['type' => 'OtherThing', 'size' => 23]]));
});

✅ Expected behavior

I would expect the validator to generate rules matching the union type (i.e. either-or) and validation to succeed with the value being of the matching type (i.e. OtherData in this test case).

🖥️ Versions

Laravel: 11.40.0
Laravel Data: 4.13.0
PHP: 8.3.9

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