PHP 8.2: true type

Version8.2
TypeNew Feature

PHP 8.2 allows using true as a type as a standalone type and as part of a Union Type.

Since PHP 8.2, true can be used as a type anywhere PHP accepts a type:

class Foo {

    private true $processed;

    public function process(string|int|true $value): true {
    }
}

true type does not coerce

When a parameter, property, or a return type is declared as true, PHP does not coerce any other type to true. This is the case even if PHP script has strict types (strict_types) disabled, and even on values that are otherwise coerced as true in non-strict comparisons.

For example, the following function call does not coerce the integer value 1 to true, and results in a TypeError:

function foo(true $value) {}

foo(1);
TypeError: foo(): Argument #1 ($value) must be of type true, int given, called in ... on line ... and defined in ...:...

Using true in Union Types

true type can be used as part of Union Types, as long as the true type is not redundant, or used along with the false type.

Following is an example of a union type declaration that uses true type:

function sendEmail(true|string): true {
    return true;
}

sendEmail(true);

PHP's bool type is essentially a union type of true|false. However, to prevent ambiguity, two of the following restrictions are enforced.

Redundancy check with bool type

true type must not be used in union with the bool type, because bool type already includes true type. Attempting to declare a union type with bool results in a compile-time fatal error:

function foo(true|bool $value) {}
Fatal error: Duplicate type true is redundant in ... on line ...

true|false Union is not allowed

Because bool type is essentially the same as true|false, using true|false as a union type is not allowed:

function foo(true|false $value) {}
Fatal error: Type contains both true and false, bool should be used instead in ... on line ...

Using true type in Intersection Types

true type cannot be used in Intersection Types at all. An Intersection Type with the true type results in a compile-time error:

function foo(true|false $value) {}
Fatal error: Type true cannot be part of an intersection type in ... on line ...

true Type Variance

The true type is considered a sub-type of the bool type, and PHP follows standard covariance and contravariance rules to the true type as well.


Covariance example where a bool return type is replaced with true type, and a union type is narrowed down in a subclass.

class Foo {
    public function test(): bool {}
    public function test2(): string|true {}
}

class FooBar extends Foo {
    public function test(): false {}
    public function test2(): true {}
}

Contravariance example where a true typed parameter is expanded to the bool type, and a union type is expanded:

class Foo {
    public function test(true $value): void {}
    public function test2(true|string $value): void {}
}

class FooBar extends Foo {
    public function test(bool $value): void {}
    public function test2(true|string|int $value): void {}
}

Related Changes

Backwards Compatibility Impact

true is a reserved keyword in PHP, and adding true as a valid type in PHP 8.2 should not cause any compatibility issues with existing PHP applications.

Note that PHP versions prior to PHP 8.2 cannot use true type either as a standalone type or a union type, and results in a fatal error at compile-time:

Fatal error: Cannot use 'true' as class name as it is reserved in ... on line ...

PHP applications that need to declare true type may use PHPDoc comments for the added expressiveness, and resort to using bool type for compatibility with older PHP versions:

/**
 * @param true $value
 */
function foo(true $value) {}

RFC Discussion Implementation