← 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.7Phan 6.0.7 php-ast version 1.1.3 PHP version used to run Phan: 8.5.9 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.2.8PHPStan - PHP Static Analysis Tool 2.2.8 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. [identifier=argument.type] [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. [identifier=argument.type]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
psalm 6.16.1Psalm 6.16.1@f1f5de594dc76faf8784e02d3dc4716c91c6f6ac
next: 7.0.0-beta19
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.46.0mago 1.46.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.70.1mir 0.70.1 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.9.0phpantom_lsp 0.9.0 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/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
phpy 0.2.0phpy 0.2.0 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
qodana 262.8665.325Qodana 262.8665.325 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.5steins 0.1.5 (2026-08-12 revision 39b4cc1) Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
phpstan-strict 2.2.8PHPStan - PHP Static Analysis Tool 2.2.8 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. [identifier=argument.type]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
psalm-next 7.0.0-beta19Psalm 7.0.0-beta19@7e751c06a756fa64dc4c759c09fe4a173afcb433 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