PHP Type

Nette\Utils\Type represents a PHP data type. It is used for analyzing, comparing, and manipulating types, whether obtained from a string or reflection.

PHP currently has a very rich type system: from scalar types (int, string), through objects and interfaces, to complex types (union A|B, intersection A&B, or disjunctive normal forms (A&B)|D). Additionally, there are special types like void, never, mixed, or relative types self and static.

Working with these types natively, especially via ReflectionType, is often cumbersome because you must recursively distinguish between ReflectionNamedType, ReflectionUnionType, and other objects. The Nette\Utils\Type class encapsulates all of this and provides a unified and intuitive API for working with any type supported by PHP.

For example, it allows you to easily check if one type accepts another (compatibility), extend types, or convert reflections into a readable notation.

Installation:

composer require nette/utils

All examples assume the following class alias is defined:

use Nette\Utils\Type;

fromReflection ($reflection): ?Type

This static method creates a Type object based on reflection. The parameter can be a ReflectionMethod or ReflectionFunction object (returns the return value type), or a ReflectionParameter or ReflectionProperty object. It resolves self, static, and parent to the actual class name. If the subject has no type, it returns null.

class DemoClass
{
	public self $foo;
}

$prop = new ReflectionProperty(DemoClass::class, 'foo');
echo Type::fromReflection($prop); // 'DemoClass'

fromString (string $type)Type

This static method creates a Type object from its string representation.

$type = Type::fromString('Foo|Bar');
echo $type;      // 'Foo|Bar'

fromValue (mixed $value)Type

Static method that creates a Type object based on the type of the passed value.

$type = Type::fromValue('hello'); // 'string'
$type = Type::fromValue(123);     // 'int'
$type = Type::fromValue(new stdClass); // 'stdClass'

For resources, it returns mixed, as PHP does not support the resource type. For anonymous classes, it returns the name of the nearest ancestor or object.

$obj = new class extends Foo { };
$type = Type::fromValue($obj);    // 'Foo'

getNames (): (string|array)[]

Returns an array of strings representing the subtypes that make up a compound type. For intersection types, it returns an array of arrays.

$type = Type::fromString('string|null'); // or '?string'
$type->getNames();  // ['string', 'null']

$type = Type::fromString('(Foo&Bar)|string');
$type->getNames();  // [['Foo', 'Bar'], 'string']

getTypes(): Type[]

Returns an array of Type objects representing the subtypes that make up a compound type:

$type = Type::fromString('string|null'); // or '?string'
$type->getTypes();  // [Type::fromString('string'), Type::fromString('null')]

$type = Type::fromString('(Foo&Bar)|string');
$type->getTypes();  // [Type::fromString('Foo&Bar'), Type::fromString('string')]

$type = Type::fromString('Foo&Bar');
$type->getTypes();  // [Type::fromString('Foo'), Type::fromString('Bar')]

getSingleName(): ?string

For simple types (including simple nullable types like ?string), returns the type name. Otherwise, returns null.

$type = Type::fromString('string|null');
echo $type;                       // '?string'
echo $type->getSingleName();      // 'string'

$type = Type::fromString('?Foo');
echo $type;                       // '?Foo'
echo $type->getSingleName();      // 'Foo'

$type = Type::fromString('Foo|Bar');
echo $type;                       // 'Foo|Bar'
echo $type->getSingleName();      // null (it's a union type)

isSimple(): bool

Returns whether it is a simple type. Simple types also include simple nullable types (e.g., ?string, ?Foo):

$type = Type::fromString('string');
$type->isSimple();       // true
$type->isUnion();        // false

$type = Type::fromString('?Foo'); // or 'Foo|null'
$type->isSimple();       // true
$type->isUnion();        // true (because it contains null)

isUnion(): bool

Returns whether it is a union type (contains |).

$type = Type::fromString('Foo&Bar');
$type->isUnion();        // true

isIntersection(): bool

Returns whether it is an intersection type (contains &).

$type = Type::fromString('Foo&Bar');
$type->isIntersection(); // true

isBuiltin(): bool

Returns whether the type is simple and also a PHP built-in type (like string, int, array, callable, etc.).

$type = Type::fromString('string');
$type->isBuiltin(); // true

$type = Type::fromString('string|int');
$type->isBuiltin(); // false

$type = Type::fromString('Foo');
$type->isBuiltin(); // false

isClass(): bool

Returns whether the type is simple and also a class name (not a built-in type like string or int).

$type = Type::fromString('string');
$type->isClass();   // false

$type = Type::fromString('Foo|null');
$type->isClass();   // true

$type = Type::fromString('Foo|Bar');
$type->isClass();   // false

isClassKeyword(): bool

Returns whether the type is one of the internal keywords self, parent, or static.

$type = Type::fromString('self');
$type->isClassKeyword();   // true

$type = Type::fromString('Foo');
$type->isClassKeyword();   // false

allows (string|Type $type)bool

The allows() method checks type compatibility. For example, it can determine if a value of a certain type could be passed as a parameter to a function expecting this type.

$type = Type::fromString('string|null');
$type->allows('string'); // true
$type->allows('null');   // true
$type->allows('Foo');    // false

$type = Type::fromString('mixed');
$type->allows('null');   // true

with (string|Type $type)Type

Returns a Type object that accepts both the original type and the one being added. It creates a so-called union type.

The method is clever and does not duplicate types unnecessarily. If you add a type that is already present, or is a superset of the current type (e.g., adding mixed to string), the result is simplified.

$type = Type::fromString('string');

// Extending to nullable string
echo $type->with('null'); // '?string'

// Creating a union type
echo $type->with('int');  // 'string|int'

// Adding a type that supersedes everything
echo $type->with('mixed'); // 'mixed'
version: 4.0 3.x