Zero Production Overhead
Install as a development dependency to enforce strict types during local testing and CI/CD pipelines, guaranteeing absolute zero performance cost in live production environments.
The first pure PHP library to enforce DocBlock types at runtime transparently without introducing any new syntax. Validates generics, array shapes, and advanced type contracts during execution.
TypePHP is the first pure PHP library that operates entirely in user-land using native stream wrappers and AST transformations. Because it requires no C-extensions or FFI, you can drop it into any PHP 8.1+ project effortlessly. It parses your standard PHPDoc annotations and enforces them the moment your code runs.
Define generic templates and TypePHP will track their state in memory per object instance:
/**
* @template T
*/
class Collection
{
/** @param T $item */
public function add(mixed $item): void { /* ... */ }
}
// Prebind T = User to this specific object instance
/** @var Collection<User> $users */
$users = new Collection();
$users->add(new User('Alice')); // Valid
$users->add(new Product('SKU-100'));
// Throws TypeError: Argument $item (template T = User) must be of type User, Product givenEnforce strict associative array structures and collections of specific objects:
/**
* @param array{status: 'active'|'pending', tags: list<non-empty-string>} $options
* @param User[] $collaborators
*/
function processBatch(array $options, array $collaborators): void
{
// ...
}
processBatch(
options: ['status' => 'active', 'tags' => ['php', 'types']],
collaborators: [new User(), new User()]
); // Valid
processBatch(
options: ['status' => 'archived', 'tags' => ['php']],
collaborators: []
);
// Throws TypeError: Argument $options['status'] must be of type ('active' | 'pending')Catch invalid parameters before your function executes, and invalid return values before they leak out:
/**
* @param positive-int $id
* @return non-empty-string
*/
function generateUserToken(int $id): string
{
return ""; // Throws TypeError: Return value must be of type non-empty-string
}
generateUserToken(-5);
// Throws TypeError: Argument $id must be of type positive-int, negative int (-5) givenTypePHP injects single-line guard rails without shifting your source file line numbers.
When an inline variable or type contract fails, framework error handlers and test runners (like Pest, PHPUnit, and Whoops) point directly to the exact line number where the invalid assignment or argument occurred in your application code:
FAILED Tests\SomeTest > test
TypeError: Variable $typeArray[3] must be of type int, string '1' given
at tests/SomeTest.php:7
3| declare(strict_types=1);
4|
5| test('test', function () {
6| /** @var array<int> */
➜ 7| $typeArray = [1, 2, 3, '1'];
8|
9| expect($typeArray)->toBeArray();
10| });