Hamlet Framework / 类型

1.0.0 2022-04-13 08:45 UTC

README

CI Status Packagist Packagist Coverage Status Psalm coverage

在PHP中指定表达式类型有几个方面

  1. 类型的最精确指定(我们假设它是psalm语法):array<int,DateTime|null>
  2. 运行时断言的顺序:assert($records instanceof array<int,DateTime|null>)
  3. 静态分析器的类型提示(目前是psalm):(array<int,DateTime|null>) $records
  4. 无需字符串操作即可推导类型的可能性:array<int,DateTime|null> || null
  5. 在安全的情况下进行类型转换的可能性,即空值应该转换为false等。

此库提供了类型指定的基本构建块。例如,以下表达式

$type = _map(
  _int(), 
  _union(
    _class(DateTime::class), 
    _null()
  )
)

创建了一个类型为Type<array<int,DateTime|null>>的对象。

在运行时断言$records的类型是array<int,DateTime|null>>

$type->assert($records);

$records转换为array<int,DateTime|null>>,并在$records无法转换为array<int,DateTime|null>>时抛出异常

return $type->cast($records);

将类型与其他类型组合,例如,使其可空array<int,DateTime|null>>|null

_union($type, _null())

类似于对象数组的类型

类似于对象数组需要更多工作。例如,类型array{id:int,name:string,valid?:bool}对应于以下结构

/** @var Type<array{id:int,name:string,valid?:bool}> */
$type = _object_like([
    'id'     => _int(),
    'name'   => _string(),
    'valid?' => _bool()
]);

相当复杂。还要注意所需的@var,因为psalm目前没有对依赖类型的支持。

如果您想断言与您的PHPDoc匹配的类型,可以使用类型解析器(正在进行中)

/** @var Type<array{id:int}> */
$type = Type::of('array{id:int}');

assert($type->matches($record));

背景

  • 完全转移到PHPStan解析,包括docblock
  • 添加联合和交集类型
  • 支持枚举
  • 支持非空类型
  • 支持元组作为int array{int,string}
  • 支持iterable|self|static|class-string
  • 提高对callables的支持
  • 将PHPStan添加到QA管道