Typed properties, and the state that is neither set nor null

7.4 arrived on 28 November with types on properties, and it introduces a state PHP has never had: a property that has been declared, has no default, and has not been assigned.

final class Order
{
    private int $id;
    private ?DateTimeImmutable $shippedAt = null;
    private string $currency = 'GBP';
}

$order = new Order();
// reading $id here throws:
//   Error: Typed property Order::$id must not be accessed
//   before initialization

That error is a feature and it will surprise people, because an untyped property read before assignment returned null with a notice. The distinction between uninitialised and null is real and useful — it separates “no value yet” from “explicitly no value” — and it means a constructor that fails partway leaves an object that throws rather than one that quietly reports null. Adding a nullable type with a null default is the escape hatch, and reaching for it everywhere throws the benefit away.