This post will go more in details of my last post about types. After reading that last post you know that a method declaration in Hack will look like this:
I will dig in to some problems that isn’t obvious at the moment.
When Child extends Base the types will work as expected.
When you are working with interfaces you need to be aware how you change the type.
Inheritance from PHP
When your Child class implements an interface from PHP. You need to be aware of what you are doing. You cant use Child::increase(int):int. This is because Base::increase says: “I’ll handle inputs of any type” and Child::increase says: “I’ll handle just ints”. Since int is a narrower type this will be throw an error saying incompatible type. You should use mixed.
If Base is a PHP interface you will get an error since the interface rely on a wider type:
Fatal error: Declaration of Child::increase() must be compatible with that of Base::increase() in /path/to/Child.hh on line 5
Methods with the same name
In Java you may have multiple methods with the same name but with different types of parameters or different parameter length. If the same applied in Hack you could write something like this:
But the type checker will raise an error here:
Foobar.hh:11:21,28: Name already bound
This is a feature not available in Hack. Java’s type checker is always running in “strict mode”. Since Hack may run in partial mode you may exclude the argument type annotation if you want to. That makes it impossible to know what method to invoke. You will find more about overloading methods in Hack this Github issue.
More about subtypes and supertypes
When you are changing the type you could return a subtype and change the arguments into a supertype. The later is not supported in Hack at the time of writing. (HHVM version 3.0.1)
This will generate an error like:
This is an object of type Child, It is incompatible with an object of type Base