跳至正文

更新日志 1.11.0 — 2024 年 3 月 27 日

重要变更

联合类型缩小的改进

映射器用于缩小联合类型的算法已得到极大改进,并且应该涵盖更多以前会妨碍映射器正常运行的边缘情况。

如果接口、类或指定结构的数组与输入匹配,它将优先于数组或标量。

(new \CuyZ\Valinor\MapperBuilder())
    ->mapper()
    ->map(
        signature: 'array<int>|' . Color::class,
        source: [
            'red' => 255,
            'green' => 128,
            'blue' => 64,
        ],
    ); // Returns an instance of `Color`

当允许多余的键时,如果输入匹配多个接口、类或指定结构的数组,则具有最多子节点的节点将被优先考虑,因为它被认为是最具体的类型:

(new \CuyZ\Valinor\MapperBuilder())
    ->allowSuperfluousKeys()
    ->mapper()
    ->map(
        // Even if the first shaped array matches the input, the second one is
        // used because it's more specific.
        signature: 'array{foo: int}|array{foo: int, bar: int}',
        source: [
            'foo' => 42,
            'bar' => 1337,
        ],
    );

如果输入与联合内的多种类型匹配,则会发生冲突并导致映射器失败:

(new \CuyZ\Valinor\MapperBuilder())
    ->mapper()
    ->map(
        // Even if the first shaped array matches the input, the second one is
        // used because it's more specific.
        signature: 'array{red: int, green: int, blue: int}|' . Color::class,
        source: [
            'red' => 255,
            'green' => 128,
            'blue' => 64,
        ],
    );

// ⚠️ Invalid value array{red: 255, green: 128, blue: 64}, it matches at
//    least two types from union.

引入AsTransformer特性

引入用于映射器的Constructor特性后,规范化器现在可以使用新的AsTransformer特性来简化变换器的注册。

namespace My\App;

#[\CuyZ\Valinor\Normalizer\AsTransformer]
#[\Attribute(\Attribute::TARGET_PROPERTY)]
final class DateTimeFormat
{
    public function __construct(private string $format) {}

    public function normalize(\DateTimeInterface $date): string
    {
        return $date->format($this->format);
    }
}

final readonly class Event
{
    public function __construct(
        public string $eventName,
        #[\My\App\DateTimeFormat('Y/m/d')]
        public \DateTimeInterface $date,
    ) {}
}

(new \CuyZ\Valinor\MapperBuilder())
    ->normalizer(\CuyZ\Valinor\Normalizer\Format::array())
    ->normalize(new \My\App\Event(
        eventName: 'Release of legendary album',
        date: new \DateTimeImmutable('1971-11-08'),
    ));

// [
//     'eventName' => 'Release of legendary album',
//     'date' => '1971/11/08',
// ]

新功能

  • 改进映射期间的联合类型缩小 ( f73158 )
  • 引入AsTransformer特性 ( 13b6d0 )

错误修复

  • 当存在多余值时处理单个数组映射( 86d021 )
  • 正确处理ArrayObject规范化 ( 4f555d )
  • 正确处理具有匹配名称和命名空间的类类型( 0f5e96 )
  • 在映射期间正确处理嵌套的不可解析类型 ( 194706 )
  • 加强类型标记提取( c9dc97 )

其他

  • 减少类型解析期间对类自动加载器的调用次数 ( 0f0e35 )
  • 重构泛型类型解析和检查( ba6770 )
  • 属性和参数的单独原生类型和文档块类型 ( 37993b )