TypeAssert::matches_type_structure can't check collections of shapes
genych opened this issue · comments
Asserts that a variable matches the given type structure; these can be arbitrary nested shapes. This is particular useful for dealing with JSON responses.
Test:
<?hh
require_once(__DIR__.'/../../../vendor/hh_autoload.php');
class X
{
const type Inner = shape('a' => int);
const type Outer = Container<self::Inner>;
public static function test(): mixed
{
$subj = [
['a' => 'completely normal int'],
];
return \Facebook\TypeAssert\matches_type_structure(type_structure(self::class, 'Outer'), $subj);
}
}
X::test();
Returns array but should throw IncorrectTypeException because of type mismatch (string instead of int). (Like Fred Emmott's typeassert: FredEmmott\TypeAssert\IncorrectTypeException' with message 'Expected type 'int', got type 'string'' in…
)
This is supported if you use a concrete container or the ConstFoo interfaces, but I missed out on Container and Traversable when migrating the internals to typespec; also doesn't verify properly with Inner = int. Will fix.
Root cause is that generics can not be supported in a universal manner - but for some commonly used classes/interfaces, it's worth hardcoding support for them.