sebastian/type
sebastian/type provides lightweight value objects that model PHP’s type system. Useful for tools and libraries that need to represent, compare, and work with types (including complex and composite types) in a consistent, structured way.
Install as a dev dependency: composer require --dev sebastian/type. Focus first on ReflectionMapper and the Type hierarchy (ObjectType, UnionType, IntersectionType, etc.). The primary use case is building or extending static analysis tools—e.g., writing a custom PHPStan rule that checks for missing @return annotations by mapping ReflectionMethod to a Type object via ReflectionMapper::fromFunctionLikeType($method->getReturnType()). Start by reviewing src/Type.php and src/ReflectionMapper.php to see how PHP’s reflection API is normalized into composable value objects.
ReflectionMapper::fromPropertyType() (added in v5.1.0) to convert ReflectionProperty::getType() into Type instances for enforcing field-level constraints (e.g., ensuring all DTO properties are typed as scalar or nullable).Type::equals() and is_subtype_of() to detect incompatible overrides (e.g., parent::save(): void vs child::save(): bool).Type objects to strings (via toString()) when scaffolding API clients or OpenAPI specs from reflection data—especially useful for union/intersection types that PHP’s native ReflectionType::__toString() doesn’t fully capture.Type::isCompatibleWith() (e.g., verify that a function returning int|float is compatible with float|int, which is considered equal under commutativity).^6.0. Verify with composer show sebastian/type—5.1.x supports up to PHP 8.3.iterable edge cases: Though fixed in 5.1.1+/6.0.2+, ReflectionMapper::fromType() historically mishandled unions like iterable|ArrayObject. Always test with edge cases (e.g., iterable|Traversable|Closure).int, string, object, unions/intersections). It does not support class-string, trait aliases, or custom user-defined types—extend Type carefully for domain-specific needs.Type objects are value objects—no setters, no mutation. If your code mutates types (e.g., appending null to a union), create a new UnionType instance.var_dump($type) on a Type instance to see its internal structure (e.g., ObjectType shows the FQCN; UnionType lists all components). Pair with Xdebug to trace reflection mapping in complex code.How can I help you explore Laravel packages today?