-
-
Notifications
You must be signed in to change notification settings - Fork 263
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