symfony/type-info
Symfony TypeInfo extracts and models PHP type information from reflections and type strings. Resolve scalars, objects, enums, generics, lists, and nullable types via TypeResolver, inspect identifiers and constraints, and stringify types like Collection.
Installation:
composer require symfony/type-info phpstan/phpdoc-parser
phpstan/phpdoc-parser is required for resolving raw string types (e.g., @var docblocks).First Use Case: Resolve a property type from a class:
use Symfony\Component\TypeInfo\TypeResolver;
$resolver = TypeResolver::create();
$type = $resolver->resolve(new \ReflectionProperty(MyClass::class, 'propertyName'));
echo (string) $type; // Outputs: e.g., "int|null"
Key Entry Points:
TypeResolver: Resolves types from Reflection* objects or strings.Type factories: Build types programmatically (e.g., Type::nullable(Type::int())).TypeIdentifier: Check type compatibility (e.g., TypeIdentifier::OBJECT).Use TypeResolver to extract types from PHP reflection objects:
$resolver = TypeResolver::create();
$propertyType = $resolver->resolve(new \ReflectionProperty(User::class, 'email'));
// Returns: Type instance for `string|null` (if nullable).
Common Reflection Sources:
ReflectionProperty)ReflectionMethod)ReflectionParameter)ReflectionClass)Example: Method Return Type
$method = new \ReflectionMethod(User::class, 'getFullName');
$returnType = $resolver->resolve($method->getReturnType());
Construct complex types using static factories:
// Nullable int
$type = Type::nullable(Type::int());
// Generic collection (e.g., `Collection<int>`)
$type = Type::generic(Type::object(Collection::class), Type::int());
// Array shape (e.g., `array{string: int}`)
$type = Type::arrayShape([
'name' => Type::string(),
'age' => Type::int(),
]);
Use Case: Define expected types for validation or API contracts.
isSatisfiedByCheck if a type meets custom conditions:
$type->isSatisfiedBy(fn (Type $t) =>
$t->isIdentifiedBy(TypeIdentifier::STRING) &&
!$t->isNullable()
);
Example: Ensure a property is a non-nullable string:
$resolver->resolve(new \ReflectionProperty(User::class, 'username'))
->isSatisfiedBy(fn (Type $t) => $t->isIdentifiedBy(TypeIdentifier::STRING) && !$t->isNullable());
Resolve types from PHPDoc annotations:
$resolver = TypeResolver::create();
$type = $resolver->resolve('@var string|null'); // From docblock
Use Case: Validate runtime types against docblock declarations.
Use TypeContextFactory with caching for repeated resolutions:
$factory = new \Symfony\Component\TypeInfo\TypeContextFactory();
$context = $factory->createFromReflectionClass(new \ReflectionClass(User::class));
$cachedResolver = new \Symfony\Component\TypeInfo\TypeResolver($context);
When to Use: In performance-critical paths (e.g., request validation).
Resolve generic types (e.g., ArrayObject<string>):
$type = Type::generic(
Type::object(ArrayObject::class),
Type::string()
);
Use Case: Type-checking collections in frameworks like Symfony’s Collection.
Cast types to strings for logging/debugging:
echo (string) Type::list(Type::int()); // Outputs: "int[]"
Use Case: Displaying types in error messages or API responses.
Type::nullable(Type::nullable(Type::int())) is redundant—Type::nullable() is idempotent.Type::nullable(Type::int()) directly.composer dump-autoload is run or use ClassLoader::addPsr4().@template-extends) may not resolve correctly.phpstan/phpdoc-parser and ensure docblocks are properly formatted.TypeContext for classes/methods to avoid repeated parsing:
$context = $factory->createFromReflectionClass(new \ReflectionClass(User::class));
$resolver = new TypeResolver($context);
@template-extends) require phpstan/phpdoc-parser.BackedEnum may be misclassified as enums.Type::enum() explicitly or update to Symfony 7.3.3+.Type::list() and Type::array() behave differently:
list: Homogeneous (e.g., int[]).array: Heterogeneous (e.g., array{string, int}).Type::arrayShape() for strict key-value pairs.$type = $resolver->resolve($property);
\Log::debug('Resolved type:', ['type' => (string) $type]);
TypeResolver to support custom type sources (e.g., database schemas).TypeIdentifier::class.array{...} syntax for stricter type hints:
function process(array{string $name, int $age} $user) { ... }
TypeInfo automatically resolves these to ArrayShapeType.| Issue | Solution |
|---|---|
TypeResolver returns null |
Ensure phpstan/phpdoc-parser is installed. |
| Generic types not resolved | Verify class names are fully qualified. |
| Docblock parsing fails | Simplify docblocks or update dependencies. |
| Performance issues | Cache TypeContext instances. |
TypeResolver in unit tests:
$mockResolver = $this->createMock(TypeResolver::class);
$mockResolver->method('resolve')->willReturn(Type::string());
How can I help you explore Laravel packages today?