Type Constants: Constraints

Constraints on type constants are similar to constraints on generic type parameters in that they restrict what the type constant may be overridden by.

Abstract Classes

A constraint on an abstract type constant requires that any class overrding the abstract type constant must be a subtype of the constraint type.

<?hh

namespace Hack\UserDocumentation\TypeConstants\Constraints\Examples\AbsClass;

abstract class AbsParent {
  abstract const type Foo as arraykey;
}

class FirstChild extends AbsParent {
  const type Foo = string; // good since string is arraykey.
}

class SecondChild extends AbsParent {
  const type Foo = float; // typechecker error since float is not an arraykey.
}

/***

abstract-type-errors.php:13:7,17: Class Hack\UserDocumentation\TypeConstants\Constraints\Examples\AbsClass\SecondChild does not correctly implement all required methods  (Typing[4110])
  abstract-type-errors.php:13:27,35: Some methods are incompatible with those declared in type Hack\UserDocumentation\TypeConstants\Constraints\Examples\AbsClass\AbsParent
Read the following to see why:
  abstract-type-errors.php:6:23,25: Unable to satisfy constraint on this type constant
  abstract-type-errors.php:6:30,37: This is an array key (int/string)
  abstract-type-errors.php:14:20,24: It is incompatible with a float

***/

Concrete Classes

A concrete class type constant must have a constraint in order for any children to override that type constant.

<?hh

namespace Hack\UserDocumentation\TypeConstants\Constraints\Examples\ConcClass;

class ParentWithConstraint {
  const type Foo as arraykey = arraykey;
}

class Child extends ParentWithConstraint {
  // good since string is arraykey and parent constrained to arraykey.
  const type Foo = string;
}

class ParentWithoutConstraint {
  const type Foo = arraykey;
}

class BadChild extends ParentWithoutConstraint {
  // Although int is an arraykey, parent not constrained to arraykey, so this
  // is a typechecker error.
  const type Foo = int;
}


/***

concrete-type-errors.php:18:7,14: Class Hack\UserDocumentation\TypeConstants\Constraints\Examples\ConcClass\BadChild does not correctly implement all required methods  (Typing[4110])
  concrete-type-errors.php:18:24,46: Some methods are incompatible with those declared in type Hack\UserDocumentation\TypeConstants\Constraints\Examples\ConcClass\ParentWithoutConstraint
Read the following to see why:
  concrete-type-errors.php:21:14,16: The assigned type of this type constant is inconsistent with its parent
  concrete-type-errors.php:21:20,22: This is an int
  concrete-type-errors.php:15:20,27: It is incompatible with an array key (int/string)

***/