← All results

Local type aliases via vendor-prefixed annotations

Group: Type aliases · Category: ecosystem · File: aliases_local_type.php

@phpstan-type / @psalm-type bind a short name to a complex shape on the declaring class. Analyzers that expand the alias reject a missing required key when the alias is used as a @param type. References: - PHPStan phpdoc-types: Local type aliases - Psalm utility_types.md: Type aliases

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.10Phan 6.0.10 php-ast version 1.1.3 PHP version used to run Phan: 8.5.11 Unrecognized
aliases_local_type.php:28: Parameter $address has undeclared type \Conformance\Tests\AliasesLocalType\UserAddress [PhanUndeclaredTypeParameter]
aliases_local_type.php:37: Argument 1 ($address) is ['street'=>'1 Main St','city'=>'Town','zip'=>'12345'] of type array{street:'1 Main St',city:'Town',zip:'12345'} but \Conformance\Tests\AliasesLocalType\User::setAddress() takes \Conformance\Tests\AliasesLocalType\UserAddress (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/aliases_local_type.php:28 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]
aliases_local_type.php:40: Argument 1 ($address) is ['street'=>'1 Main St','city'=>'Town'] of type array{street:'1 Main St',city:'Town'} but \Conformance\Tests\AliasesLocalType\User::setAddress() takes \Conformance\Tests\AliasesLocalType\UserAddress (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/aliases_local_type.php:28 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]
  • Recognition: spelling not resolved — reported on declaration line(s) 28
  • Enforcement: 1/1 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 37: Expected valid value to be accepted, got ["Argument 1 ($address) is ['street'=>'1 Main St','city'=>'Town','zip'=>'12345'] of type array{street:'1 Main St',city:'Town',zip:'12345'} but \\Conformance\\Tests\\AliasesLocalType\\User::setAddress() takes \\Conformance\\Tests\\AliasesLocalType\\UserAddress (no real type) defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/aliases_local_type.php:28 (the inferred real argument type has nothing in common with the parameter's phpdoc type) [PhanTypeMismatchArgumentProbablyReal]"]
phpstan 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Enforced reported Lv.5+
aliases_local_type.php:40: Parameter #1 $address of method Conformance\Tests\AliasesLocalType\User::setAddress() expects array{street: string, city: string, zip: string}, array{street: '1 Main St', city: 'Town'} given. [reported-from-level=5]
With strict-rules
aliases_local_type.php:40: Parameter #1 $address of method Conformance\Tests\AliasesLocalType\User::setAddress() expects array{street: string, city: string, zip: string}, array{street: '1 Main St', city: 'Town'} given.
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
psalm 6.20.0Psalm 6.20.0@804f03c0c183d149fcd4b8c7c0c9b3fbf836d34c
next: 7.0.0-rc2
Enforced
aliases_local_type.php:40: Argument 1 of Conformance\Tests\AliasesLocalType\User::setAddress expects array{city: string, street: string, zip: string}, but array{city: 'Town', street: '1 Main St'} provided [InvalidArgument]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
mago 1.57.0mago 1.57.0 Enforced
aliases_local_type.php:40: Possible argument type mismatch for argument #1 of `Conformance\Tests\AliasesLocalType\User::setAddress`: expected `array{'city': string, 'street': string, 'zip': string}`, but possibly received `array{'city': string('Town'), 'street': string('1 Main St')}`. [possibly-invalid-argument]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
mir 0.87.0mir 0.87.0 Enforced
aliases_local_type.php:40: InvalidArgument: Argument $address of setAddress() expects 'array{'street': string, 'city': string, 'zip': string}', got 'array{'street': "1 Main St", 'city': "Town"}' [MIR0201]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
phpantom 0.11.1phpantom_lsp 0.11.1 Enforced
aliases_local_type.php:40: Argument 1 ($address) expects array{street: string, city: string, zip: string}, got array{street: '1 Main St', city: 'Town'} (missing required key 'zip') [type_mismatch_argument]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
intelephense 1.18.5intelephense 1.18.5 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
phpactor 2026.10.07.0Phpactor 2026.10.07.0 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
phpy 1.0.19409phpy 1.0.19409 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
qodana 262.10968.76PhpStorm 262.10968.76 Enforced
aliases_local_type.php:40: Incomplete array according to shape declaration. Missing key(s): zip [PhpMissingArrayKeyInspection]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
noverify 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 Unrecognized
aliases_local_type.php:26: Class or interface named \Conformance\Tests\AliasesLocalType\UserAddress does not exist [undefinedClass]
  • Recognition: spelling not resolved — reported on declaration line(s) 26
  • Enforcement: 0/1 of the expected violations reported — incidental, since the spelling was not resolved
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Enforced
aliases_local_type.php:40: argument ['street' => '1 Main St', 'city' => 'Town'] to User::setAddress() violates declared @param array{street: string, city: string, zip: string} $address — declared contract violation [phpdoc.param-mismatch]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
phpstan-strict 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Enforced
aliases_local_type.php:40: Parameter #1 $address of method Conformance\Tests\AliasesLocalType\User::setAddress() expects array{street: string, city: string, zip: string}, array{street: '1 Main St', city: 'Town'} given.
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
psalm-next 7.0.0-rc2Psalm 7.0.0-rc2@20339e3fe5b8d03bcd8061030eb2a83ad50e5783 Enforced
aliases_local_type.php:40: Argument 1 of Conformance\Tests\AliasesLocalType\User::setAddress expects array{city: string, street: string, zip: string}, but array{city: 'Town', street: '1 Main St'} provided [InvalidArgument]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\AliasesLocalType;

/**
 * Local type aliases via vendor-prefixed annotations.
 *
 * `@phpstan-type` / `@psalm-type` bind a short name to a complex shape on the
 * declaring class. Analyzers that expand the alias reject a missing required
 * key when the alias is used as a `@param` type.
 *
 * References:
 * - PHPStan phpdoc-types: Local type aliases
 * - Psalm utility_types.md: Type aliases
 */

/**
 * @phpstan-type UserAddress array{street: string, city: string, zip: string}
 * @psalm-type UserAddress = array{street: string, city: string, zip: string}
 */
final class User // T: @phpstan-type / @psalm-type
{
    /**
     * @param UserAddress $address
     */
    public function setAddress($address): void // T: UserAddress
    {
    }
}

$user = new User();

// Valid complete shape — tools that model the alias accept. An analyzer that
// treats the alias as a class name rejects this too (incidental, not enforcement).
$user->setAddress(['street' => '1 Main St', 'city' => 'Town', 'zip' => '12345']); // V

// Missing required key `zip` — alias expansion should reject this shape.
$user->setAddress(['street' => '1 Main St', 'city' => 'Town']); // E?: incomplete UserAddress shape should be rejected