hhvm/type-assert

该软件包已被废弃,不再维护。未建议替代软件包。

将无类型数据转换为有类型数据

安装次数: 1,058,222

依赖者: 25

建议者: 0

安全性: 0

星标: 25

关注者: 18

分支: 12

开放问题: 7

语言:Hack

v4.2.2 2021-09-13 15:44 UTC

README

Continuous Integration

Hack库,用于将无类型数据转换为有类型数据。

关于TypeAssert\matches_type_structure()的警告

TypeStructure<T>type_structure()ReflectionTypeAlias::getTypeStructures()是HHVM的实验性功能,不受Facebook或HHVM团队支持。这意味着matches_type_structure()可能会在未来版本中未经警告就被移除。

我们强烈建议改为使用TypeAssert\matches<T>()TypeCoerce\match<T>()

安装

composer require hhvm/type-assert

用法

TypeAssert提供接受混合输入的函数,要么返回未修改的值(但带有类型数据),要么抛出异常;例如

<?hh // strict
use namespace Facebook\TypeAssert;
function needs_string(string $bar): void {
}

function main(): void {
  needs_string(TypeAssert\string('foo')); // type-safe and works fine
  needs_string(TypeAssert\string(123)); // type-safe, but throws
}

包括

  • string(mixed): string
  • int(mixed): int
  • float(mixed): float
  • bool(mixed): bool
  • resource(mixed): resource
  • num(mixed): num
  • arraykey(mixed): arraykey
  • not_null<T>(?T): T
  • instance_of<T>(classname<T>, mixed): T
  • classname_of<T>(classname<T>, mixed): classname<T>
  • matches<T>(mixed): T
  • matches_type_structure<T>(TypeStructure<T>, mixed): T

强制转换

TypeAssert还包含Facebook\TypeCoerce命名空间,它包含一组类似的功能

  • string(mixed): string
  • int(mixed): int
  • float(mixed): float
  • bool(mixed): bool
  • resource(mixed): resource
  • num(mixed): num
  • arraykey(mixed): arraykey
  • match<T>(mixed): T
  • match_type_structure<T>(TypeStructure<T>, mixed): T

这些将执行安全的转换,例如将“int-ish”字符串转换为int,将int转换为字符串,将数组转换为向量,将数组转换为字典等。

类型规范

您还可以在没有类型结构的情况下断言/强制转换复杂类型(除了形状和元组)

<?hh

use namespace Facebook\TypeSpec;

$spec = TypeSpec\dict(
  TypeSpec\string(),
  TypeSpec\int(),
);
$x = $spec->assertType(dict['foo' => 123]); // passes: $x is a dict<string, int>
$x = $spec->assertType(dict['foo' => '123']); // fails
$x = $spec->assertType(dict[123 => 456]); // fails
$x = $spec->assertType(dict[123 => 456]); // fails

$x = $spec->coerceType(dict[123 => '456']); // passes: $x is dict['123' => 456];

由于它们不能被泛化表示,因此不支持形状和元组。

matches_type_structure<T>(TypeStructure<T>, mixed): T

断言变量与给定的类型结构匹配;这些可以是任意嵌套的形状。这对于处理JSON响应特别有用。

<?hh // strict

use namespace Facebook\TypeAssert;

class Foo {
  const type TAPIResponse = shape(
    'id' => int,
    'user' => string,
    'data' => shape(
      /* ... */
    ),
  );

  public static function getAPIResponse(): self::TAPIResponse {
    $json_string = file_get_contents('https://api.example.com');
    $array = json_decode($json_string, /* associative = */ true);
    return TypeAssert\matches_type_structure(
      type_structure(self::class, 'TAPIResponse'),
      $array,
    );
  }
}

您可以使用type_structure()为类型常量获取TypeStructure<T>,或使用ReflectionTypeAlias::getTypeStructure()获取顶层类型别名。

not_null<T>(?T): T

如果它是null则抛出异常,否则细化类型 - 例如

<?hh // strict
use namespace \Facebook\TypeAssert;

function needs_string(string $foo): void {}
function needs_int(int $bar): void {}

function main(?string $foo, ?int bar): void {
  needs_string(TypeAssert\not_null($foo)); // ?string => string
  needs_int(TypeAssert\not_null($bar)); // ?int => int
}

is_instance_of<T>(classname<T>, mixed): T

断言输入是给定类型的对象;例如

<?hh
use namespace Facebook\TypeAssert;

class Foo {}

function needs_foo(Foo $foo): void {}

function main(mixed $foo): void {
  needs_foo(TypeAssert::is_instance_of(Foo::class, $foo));
}

main(new Foo());

is_classname_of<T>(classname<T>, mixed): classname<T>

断言输入是指定类子类的名称,或者实现了指定的接口。

<?hh // strict
use namespace Facebook\TypeAssert;

class Foo {
  public static function doStuff(): void {}
}
class Bar extends Foo {
  <<__Override>>
  public static function doStuff(): void {
    // specialize here
  }
}

function needs_foo_class(classname<Foo> $foo): void {
  $foo::doStuff();
}

function main(mixed $class): void {
  needs_foo_class(TypeAssert::is_classname_of(Foo::class, $class));
}

main(Bar::class);

致谢

此库是以下想法的重新实现:

  • @admdikramr
  • @ahupp
  • @dlreeves
  • @periodic1236
  • @schrockn

安全问题

我们使用GitHub问题跟踪公开的bug。请确保您的描述清晰,并包含足够的说明,以便能够重现问题。

Facebook有一个赏金计划,用于安全地披露安全漏洞。在这些情况下,请按照该页面上的说明进行操作,不要提交公开问题。

许可证

Type-Assert遵循MIT许可证。