hhvm / type-assert

Hack library for converting untyped data to typed data.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.