Serde icon indicating copy to clipboard operation
Serde copied to clipboard

Deserialize type error when using flatten

Open KorvinSzanto opened this issue 2 months ago • 0 comments

If a child class has the same property name but different type as a parent class, serde serializes but fails to deserialize.

See this example:

<?php

require_once('./vendor/autoload.php');

readonly class B
{
    public function __construct(public int $id) {}
}

readonly class A
{
    public function __construct(
        public string $id,
        #[\Crell\Serde\Attributes\Field(flatten: true, flattenPrefix: 'b_')]
        public B $b,
    ) {}
}

$serde = new \Crell\Serde\SerdeCommon();
$serialized = $serde->serialize(new A('test', new B(123)), 'array');
$result = $serde->deserialize($serialized, 'array', A::class);
var_dump($result);

throws the fatal:

PHP Fatal error:  Uncaught Crell\Serde\TypeMismatch: Expected value of type int when writing to property id, but found type string.  Either your incoming data is invalid, or perhaps the field needs to be in non-strict mode. in /home/coder/defaultsite/vendor/crell/serde/src/TypeMismatch.php:16
Stack trace:
#0 /home/coder/defaultsite/vendor/crell/serde/src/Formatter/ArrayBasedDeformatter.php(38): Crell\Serde\TypeMismatch::create()
#1 /home/coder/defaultsite/vendor/crell/serde/src/PropertyHandler/ScalarExporter.php(27): Crell\Serde\Formatter\ArrayFormatter->deserializeInt()
#2 /home/coder/defaultsite/vendor/crell/serde/src/Deserializer.php(31): Crell\Serde\PropertyHandler\ScalarExporter->importValue()
#3 /home/coder/defaultsite/vendor/crell/serde/src/Formatter/ArrayBasedDeformatter.php(289): Crell\Serde\Deserializer->deserialize()
#4 /home/coder/defaultsite/vendor/crell/serde/src/PropertyHandler/ObjectImporter.php(24): Crell\Serde\Formatter\ArrayFormatter->deserializeObject()
#5 /home/coder/defaultsite/vendor/crell/serde/src/Deserializer.php(31): Crell\Serde\PropertyHandler\ObjectImporter->importValue()
#6 /home/coder/defaultsite/vendor/crell/serde/src/Serde.php(114): Crell\Serde\Deserializer->deserialize()
#7 /home/coder/defaultsite/test.php(21): Crell\Serde\Serde->deserialize()
#8 {main}
  thrown in /home/coder/defaultsite/vendor/crell/serde/src/TypeMismatch.php on line 16

KorvinSzanto avatar Oct 18 '25 00:10 KorvinSzanto