PHPackages                             forrest79/type-validator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. forrest79/type-validator

ActivePhpstan-extension[Utility &amp; Helpers](/categories/utility)

forrest79/type-validator
========================

TypeValidator provides functionality to check types with PHP Doc syntax in runtime and narrow types for PHPStan.

v1.3.0(3w ago)71.7k↓53.3%11BSD-3-ClausePHPPHP ^8.3CI passing

Since Apr 30Pushed 3w ago1 watchersCompare

[ Source](https://github.com/forrest79/type-validator)[ Packagist](https://packagist.org/packages/forrest79/type-validator)[ RSS](/packages/forrest79-type-validator/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (16)Versions (12)Used By (1)

TypeValidator
=============

[](#typevalidator)

[![Latest Stable Version](https://camo.githubusercontent.com/80f586ce871da047cc95f1224d87d241039869975609827b08908c1403b577cc/68747470733a2f2f706f7365722e707567782e6f72672f666f727265737437392f747970652d76616c696461746f722f76)](//packagist.org/packages/forrest79/type-validator)[![Monthly Downloads](https://camo.githubusercontent.com/01165eee607da21e7e125d5eb2575c6c7f5e06e58003585aabdda167b84a78a4/68747470733a2f2f706f7365722e707567782e6f72672f666f727265737437392f747970652d76616c696461746f722f642f6d6f6e74686c79)](//packagist.org/packages/forrest79/type-validator)[![License](https://camo.githubusercontent.com/14406fd50ce3a7348714519c79be572e183f78ee8bd99de8e6feda87b9a2672d/68747470733a2f2f706f7365722e707567782e6f72672f666f727265737437392f747970652d76616c696461746f722f6c6963656e7365)](//packagist.org/packages/forrest79/type-validator)[![Build](https://github.com/forrest79/type-validator/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/forrest79/type-validator/actions/workflows/build.yml)[![codecov](https://camo.githubusercontent.com/c29135dcf86ba6d0af8889e14dd33b3c82b46d71e4134d686019f1659bf51fbe/68747470733a2f2f636f6465636f762e696f2f67682f666f727265737437392f747970652d76616c696461746f722f67726170682f62616467652e7376673f746f6b656e3d53594a434a58435a3649)](https://codecov.io/gh/forrest79/type-validator)

Introduction
------------

[](#introduction)

Validates types using PHP Doc descriptions and narrows types for [PHPStan](https://phpstan.org/).

Imagine you're loading data from some external source. For PHP, this is mostly `mixed` (or some other common type like `array`/`object`), and PHPStan is unhappy with this. If data is some simple type, most of us will add something like:

```
assert(is_int($data)); // if we know, there will be always an int
if (!is_int($data)) throw new InvalidDataException(); // if we want to check this also in runtime
```

Both make PHPStan happy, and you code is also tested (the first example mostly in dev environment, where the assertion is on).

But when the loaded data is a complex type like `list`.

Checking this at runtime and making PHPStan happy is now harder. The goal of this library is to make this as simple as `assert(is_int($data))`.

Use `assert(is_type($data, 'list'))` and the variable is really checked for the correct type at runtime, and the type is also narrowed for PHPStan.

> Code coverage is computed without PHPStan extension - only the PHP runtime part.

Installation
------------

[](#installation)

To use this extension, require it in [Composer](https://getcomposer.org/):

```
composer require --dev forrest79/type-validator

```

> You probably only want this extension for development, but it can also be used in production (omit `--dev`).

Using
-----

[](#using)

There is one global function `is_type(mixed $var, string $type)` and static methods `Forrest79\TypeValidator::isType(mixed $var, string $type): bool` or `Forrest79\TypeValidator::checkType(mixed $var, string $type): void`.

All of them really check the data in `$var` against the type description and there is corresponding PHPStan extension so PHPStan will understand, that `$var` is in described type.

The function `is_type(mixed $var, string $type)` and method `Forrest79\TypeValidator::isType(mixed $var, string $type)` return a `bool` - true if `$var` matches the `$type`, and `false` otherwise.

The Method `Forrest79\TypeValidator::checkType(mixed $var, string $type)` has no return, but it throws a `CheckException`, if `$var` does not match the `$type`.

Example:

```
$arr = [3.14, 5, 10];
assert(is_type($arr, 'list'));
assert(Forrest79\TypeValidator::isType($arr, 'list'));
Forrest79\TypeValidator::checkType($arr, 'list'));
```

With this you can replace your `@var` annotations:

```
/** @var array $arr
$arr = json_decode($data);
```

With:

```
$arr = json_decode($data);
assert(is_type($arr, 'array'));
```

The benefit is that variable `$arr` is checked for defined type.

Almost all PHPDoc types from PHPStan are supported (more information about supported types is provided later in the docs).

To use this library as PHPStan extension include `extension.neon` in your project's PHPStan config:

```
includes:
    - vendor/forrest79/type-validator/extension.neon
```

> Because of PHPStan, the type description must be a static string—nothing can be generated dynamically.

### Use in production

[](#use-in-production)

Typically, the `assert` function is disabled in production, so checks are only performed in development/test environments, and there is no need to distribute this library in a production environment.

But you can use this for validation also in your production code. Parsing PHPDoc types is not too performance-intensive. This library depends on `phpstan/phpdoc-parser` for parsing types and `nikic/php-parser` for detection fully qualified class names.

### FQN (Fully qualified names)

[](#fqn-fully-qualified-names)

Correct fully qualified names are computed from the current namespace and `use` statements, just like every other item in your PHP source files. However, if you use a `use` statement only for this library, your IDE and PHPCS may mark it as unused because they don't know about this library:

Example:

```
namespace App;

use App\Presenter; // this use is marked as unused

assert($presenter, 'class-string'); // even though it is correctly used here
```

One solution is to concatenate the type string with `::class` such as `assert($presenter, 'class-string')`. However, this looks very ugly. I prefer to use an FQN in the type description and omit the `use` statement:

```
namespace App;

assert($presenter, 'class-string');
```

### Supported PHPStan - PHPDoc Types

[](#supported-phpstan---phpdoc-types)

According to

✅ supported 🚫 not supported - doesn't make sense for variables ❌ not supported

#### Basic types ✅/🚫/❌

[](#basic-types-)

- `int`, `integer` ✅
- `string`, `non-empty-string`, `non-empty-lowercase-string`, `non-empty-uppercase-string`, `truthy-string`, `non-falsy-string`, `lowercase-string`, `uppercase-string` ✅
- `literal-string`, `non-empty-literal-string` ❌
- `numeric-string` ✅
- `__stringandstringable` (`string` or object implementing `Stringable` interface or object with `__toString()` method) ✅
- `array-key` ✅
- `bool`, `boolean`, `true`, `false` ✅
- `null` ✅
- `float`, `double` ✅
- `number`, `numeric` ✅
- `scalar`, `empty-scalar`, `non-empty-scalar` ✅
- `array`, `associative-array`, `non-empty-array` ✅
- `list`, `non-empty-list` ✅
- `iterable` ✅
- `callable`, `callable-string`, `callable-array`, `callable-object` ✅, `pure-callable` ❌
- `resource`, `open-resource`, `closed-resource` ✅
- `object` ✅
- `empty` ✅
- `mixed`, `non-empty-mixed` ✅
- `class-string`, `interface-string`, `trait-string`, `enum-string` ✅
- `void` 🚫

#### Classes and interfaces ✅

[](#classes-and-interfaces-)

#### Integer ranges ✅

[](#integer-ranges-)

- `positive-int` ✅
- `negative-int` ✅
- `non-positive-int` ✅
- `non-negative-int` ✅
- `non-zero-int` ✅
- `int` ✅
- `int` ✅
- `int` ✅

#### General arrays ✅

[](#general-arrays-)

- `Type[]` ✅
- `array` ✅
- `array` ✅
- `non-empty-array` ✅
- `non-empty-array` ✅

#### Lists ✅

[](#lists-)

- `list` ✅
- `non-empty-list` ✅

#### Key and value types of arrays and iterables ❌

[](#key-and-value-types-of-arrays-and-iterables-)

- `key-of` ❌
- `value-of` ❌
- `value-of` ❌

#### Iterables ❌ (there can be some side effect while iterate in runtime to check correct type)

[](#iterables--there-can-be-some-side-effect-while-iterate-in-runtime-to-check-correct-type)

- `iterable` ❌
- `Collection` ❌
- `Collection` ❌
- `Collection|Type[]` ❌

#### Union types ✅

[](#union-types-)

- `Type1|Type2` ✅

#### Intersection types ✅

[](#intersection-types-)

- `Type1&Type2` ✅

#### Parentheses ✅

[](#parentheses-)

- `(Type1&Type2)|Type3` ✅

#### self, static, parent and $this 🚫

[](#self-static-parent-and-this-)

- `self`, `static`, `parent` or `$this` 🚫

#### Generics ✅/🚫/❌ (some yes, some no, some doesn't make sense - concrete info can be found in the other types description)

[](#generics--some-yes-some-no-some-doesnt-make-sense---concrete-info-can-be-found-in-the-other-types-description)

#### Conditional return types 🚫

[](#conditional-return-types-)

#### Utility types for generics ❌

[](#utility-types-for-generics-)

- `template-type` ❌
- `new` ❌

#### class-string, interface-string ✅

[](#class-string-interface-string-)

- `class-string` ✅
- `interface-string` ✅

#### Global type aliases ❌

[](#global-type-aliases-)

#### Local type aliases ❌

[](#local-type-aliases-)

#### Array shapes ✅

[](#array-shapes-)

- `array{'foo': int, "bar": string}` ✅
- `array{'foo': int, "bar"?: string}` ✅
- `array{int, int}` ✅
- `array{0: int, 1?: int}` ✅
- `array{foo: int, bar: string}` ✅

#### Object shapes ✅

[](#object-shapes-)

- `object{'foo': int, "bar": string}` ✅
- `object{'foo': int, "bar"?: string}` ✅
- `object{foo: int, bar?: string}` ✅
- `object{foo: int, bar?: string}&\stdClass` ✅

#### Literals and constants ✅/❌

[](#literals-and-constants--)

- `234` ✅
- `1.0` ✅
- `'foo'|'bar'` ✅
- `Foo::SOME_CONSTANT` ❌
- `Foo::SOME_CONSTANT|Bar::OTHER_CONSTANT` ❌
- `self::SOME_*` ❌
- `Foo::*` ❌

#### Global constants ✅

[](#global-constants-)

- `SOME_CONSTANT` ✅
- `SOME_CONSTANT|OTHER_CONSTANT` ✅

#### Callables ❌ (only simple callable is supported)

[](#callables--only-simple-callable-is-supported)

- `callable(int, int): string` ❌
- `callable(int, int=): string` ❌
- `callable(int $foo, string $bar): void` ❌
- `callable(string &$bar): mixed` ❌
- `callable(float ...$floats): (int|null)` ❌
- `callable(float...): (int|null)` ❌
- `\Closure(int, int): string` ❌
- `pure-callable(int, int): string` ❌
- `pure-Closure(int, int): string` ❌

#### Bottom type 🚫

[](#bottom-type-)

- `never` 🚫
- `never-return` 🚫
- `never-returns` 🚫
- `no-return` 🚫

#### Integer masks ✅/❌

[](#integer-masks-)

- `int-mask` ✅
- `int-mask-of` ✅
- `int-mask-of` ❌

#### Offset access ❌

[](#offset-access-)

###  Health Score

54

—

FairBetter than 96% of packages

Maintenance95

Actively maintained with recent releases

Popularity27

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 94.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~113 days

Recently: every ~50 days

Total

11

Last Release

24d ago

Major Versions

v0.4 → v1.0.02025-10-07

PHP version history (2 changes)v0.1.0PHP ^8.1

v1.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/d979cd353c6593b44b50f90ff5a5eb4be224f501a70f7cce89d0735867e488e5?d=identicon)[forrest79](/maintainers/forrest79)

---

Top Contributors

[![forrest79](https://avatars.githubusercontent.com/u/160766?v=4)](https://github.com/forrest79 "forrest79 (34 commits)")[![vrana](https://avatars.githubusercontent.com/u/117453?v=4)](https://github.com/vrana "vrana (2 commits)")

---

Tags

PHPStanvalidatorarraylisttypesnarrow

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/forrest79-type-validator/health.svg)

```
[![Health](https://phpackages.com/badges/forrest79-type-validator/health.svg)](https://phpackages.com/packages/forrest79-type-validator)
```

###  Alternatives

[zircote/swagger-php

Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations

5.3k144.5M599](/packages/zircote-swagger-php)[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k11.2M99](/packages/dedoc-scramble)[deptrac/deptrac

Deptrac is a static code analysis tool that helps to enforce rules for dependencies between software layers.

3.0k8.8M117](/packages/deptrac-deptrac)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[dereuromark/cakephp-ide-helper

CakePHP IdeHelper Plugin to improve auto-completion

1882.3M43](/packages/dereuromark-cakephp-ide-helper)[phparkitect/phparkitect

Enforce architectural constraints in your PHP applications

9224.3M28](/packages/phparkitect-phparkitect)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
