Description
✏️ 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