PHP TypeLang Help

Syntax Comparison

The language is defined by a syntax that is based on the grammar of popular static code analysis tools: PHPStan and Psalm.

General table across all type parsing capabilities

  TypeLang

  Psalm

  PHPStan

Basic Types

Below is a list of simple, logical and other common types.

  TypeLang

  Psalm

  PHPStan

Class or type name (including FQN)

Fully\Qualified\Name

Logical union types

T | U | V

Logical intersection types

T & U & V

Logical nullable types

?T

Legacy list types syntax

User[]

Template arguments (Generics)

ExampleCollection<array-key, User>

Trailing comma not supported 1

1. Psalm does NOT support arguments ending with a comma
ExampleCollection<array-key, User,>

Open in psalm.dev

Template argument hints

ExampleCollection<in array-key, out User>

Not Supported

Call-site variance 1

1. PHPStan supports call-site variance
Collection<covariant Animal>

Open in phpstan.org

Template argument attributes

ExampleCollection<#[assert(not<"0">)] array-key>

Not Supported

Not Supported

Class constant types

ClassName::CONSTANT_NAME

Prefixed class constant mask types

ClassName::CONSTANT_*

Non-prefixed class constant mask types

ClassName::*

Global constant mask types

JSON_*

Not Supported

Not Supported

Conditional Types

Below is a list of conditional types.

  TypeLang

  Psalm

  PHPStan

Conditional positive equality types

T is A ? B : C

Conditional negative equality types

T is not A ? B : C

Conditional referenced types

$var is A ? B : C $var is not A ? B : C

Conditional referenced types in Yoda-style

A is $var ? B : C A is not $var ? B : C

Not Supported

Not Supported

Functions in conditional types

foo() is A ? B : C foo() is not A ? B : C

List of supported functions 1

List of supported functions 2

1. Psalm supports the following functions
  • define()

  • array_map()

  • array_filter()

  • func_get_arg()

  • func_get_args()

  • func_num_args()

  • is_a()

  • is_subclass_of()

  • class_alias()

2. PHPStan supports the following functions
  • func_get_arg()

  • func_get_args()

  • func_num_args()

Functions in conditional types in Yoda-style

A is foo() ? B : C A is not foo() ? B : C

Not Supported

Not Supported

Literal Types

Below is a list of literal types/lexemes.

  TypeLang

  Psalm

  PHPStan

Boolean true and false literals

true false

The null literals

null

Single-quoted string literals

'single-quoted string'

Double-quoted string literals

"double-quoted string"

Escape sequences in a double-quoted string literals

"string with \n new line \n delimiters"

Not Supported

Not Supported

Hexadecimal sequences in a double-quoted string literals

"\xDE\xAD\xBE\xEF"

Not Supported

Not Supported

Unicode sequences in a double-quoted string literals

"This is smile \u{1F60A}"

Not Supported

Not Supported

Integer literals

42

BigInteger (PHP_INT_MAX + 1 or PHP_INT_MIN - 1) literals

42

Works with restrictions 1

Works with restrictions 2

Works with restrictions 3

1. TypeLang limits value to min/max int and store literal value as string
// Input 9999999999999999999
// Stored TypeLang\Parser\Node\Literal\IntLiteralNode { +offset: 0 +raw: "9999999999999999999" +value: 9223372036854775807 }
2. Psalm limits value to min/max int
// Input 9999999999999999999
// Stored 9223372036854775807

Open in psalm.dev

3. PHPStan limits value to min/max int
// Input 9999999999999999999
// Stored 9223372036854775807

Open in phpstan.org

Integer literals in binary format

0b10101010

Not Supported

Not Supported

Integer literals in octal format

0o42

Not Supported

Not Supported

Integer literals in legacy octal format

042

Not Supported

Not Supported

Integer literals in hexadecimal format

0xDEAD_BEEF

Not Supported

Not Supported

Float literals

0.42

Float literals without leading zero

.42

Not Supported

Float literals without trailing zero

42.

Not Supported

Float literals in scientific notation

2e2

Not Supported

Float literals in scientific notation

2e2

Not Supported

Float hexadecimal literals in scientific notation

0x42e2

Not Supported

Not Supported

Shape Types

Below is a list of grammar of shaped types.

  TypeLang

  Psalm

  PHPStan

Explicit shape types

object { key: ValueType }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { key: ValueType }
// Error Custom\ObjectType { key: ValueType }

Open in psalm.dev

Trailing comma in explicit shape types

object { key: ValueType, }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { key: ValueType, }
// Error Custom\ObjectType { key: ValueType, }

Open in psalm.dev

Implicit shape types

object { ValueType }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { ValueType }
// Error Custom\ObjectType { ValueType }

Open in psalm.dev

Trailing comma in implicit shape types

object { ValueType, }

Not Supported

Optional keys in explicit shape types

object { key?: ValueType }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { key?: ValueType }
// Error Custom\ObjectType { key?: ValueType }

Open in psalm.dev

Empty (closed) shape types

object {}

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object {}
// Error Custom\ObjectType {}

Open in psalm.dev

Unsealed shape types

object { ... }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { ... }
// Error Custom\ObjectType { ... }

Open in psalm.dev

Explicit unsealed shape types

object { key: ValueType, ... }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { key: ValueType, ... }
// Error Custom\ObjectType { key: ValueType, ... }

Open in psalm.dev

Implicit unsealed shape types

object { ValueType, ... }

Works with restrictions 1

1. Psalm does not support custom (class instances) objects
// OK object { ValueType, ... }
// Error Custom\ObjectType { ValueType, ... }

Open in psalm.dev

Typed unsealed shape types

object { ...<array-key, Type> }

Works with restrictions 1

Works with restrictions 2

1. Psalm does not support custom (class instances) objects
// OK object { ...<array-key, Type> }
// Error Custom\ObjectType { ...<array-key, Type> }

Open in psalm.dev

2. PHPStan does not support some built-in types such as list (hardcoded in the parser)
// OK array { ...<array-key, Type> }
// Syntax Error list { array-key, ...<Type> }

Open in phpstan.org

Shape field attributes

object { #[inline, assert(not<"">)] name: string }

Callables Types

Below is a list of grammar of callable (function) types.

  TypeLang

  Psalm

  PHPStan

Non-typed callable types

callable()

Not Supported

Typed callable types

callable(): Type

Callable with typed parameters

callable(Type): T

Callable with optional parameters

callable(Type=): T

Callable with named parameters

callable(Type $name): T

Callable with optional named parameters

callable(Type $name=): T

Not Supported

Callable with output parameters

callable(T&): T

Works with restrictions 1

1. Psalm does NOT support literal types
// OK callable(T&): U
// Bug: Intersection types must be all objects, // Psalm\Type\Atomic\TInt provided in docblock callable(int&): U

Open in psalm.dev

Callable with output optional parameters

callable(T&=): T

Works with restrictions 1

1. Psalm does NOT support literal types
// OK callable(T&=): U
// Bug: Intersection types must be all objects, // Psalm\Type\Atomic\TInt provided in docblock callable(int&=): U

Open in psalm.dev

Callable with output optional named parameters

callable(T &$name=): T

Not Supported

Callable with suffixed variadic parameters

callable(Type...): T

Callable with prefixed variadic parameters

callable(...Type): T

Not Supported

Callable with prefixed and suffixed variadic parameters

callable(...Type ...$name): T

Works with restrictions 1

Works with restrictions 2

1. Psalm throws an internal error instead of a valid error message
callable(...int ...$name) // Internal Psalm error on line ...: // Unrecognised parse tree type Psalm\Internal\Type\ParseTree\CallableParamTree

Open in psalm.dev

2. PHPStan does not support prefixed variadic parameters
callable(...int ...$name) // PHPDoc tag @return has invalid value (callable(...int ...$name): T): // Unexpected token "(", expected TOKEN_HORIZONTAL_WS at ...

Open in phpstan.org

Callable with optional variadic parameters

callable(Type...=): T callable(...Type=): T

Works with restrictions 1

No Error

1. Psalm error depends on parameter definition syntax
// OK: Cannot have variadic param with a default in docblock callable(...T=): T
// Bug: Cannot have duplicate tokens in docblock callable(T...=): T

Open in psalm.dev

Callable with named variadic parameters

callable(Type ...$name): T callable(...Type $name): T

Works with restrictions 1

Works with restrictions 2

1. Psalm throws an internal error if using prefix syntax
callable(...Type $name): T // Internal Psalm error on line ...: // Unrecognised parse tree type Psalm\Internal\Type\ParseTree\CallableParamTree

Open in psalm.dev

2. PHPStan does not support prefixed variadic parameters
callable(...Type $name): T // PHPDoc tag @return has invalid value (callable(...Type $name): T): // Unexpected token "(", expected TOKEN_HORIZONTAL_WS at ...

Open in phpstan.org

Callable with output named variadic parameters

callable(Type &...$name): T callable(...Type &$name): T

Works with restrictions 1

Works with restrictions 2

1. Psalm does NOT support literal types
// OK callable(T &...$name): U
// Bug: Intersection types must be all objects, // Psalm\Type\Atomic\TInt provided in docblock callable(int &...$name): U

Open in psalm.dev

2. PHPStan does not support prefixed variadic parameters
callable(...Type &$name): T // PHPDoc tag @return has invalid value (callable(...Type &$name): T): // Unexpected token "(", expected TOKEN_HORIZONTAL_WS at ...

Open in phpstan.org

03 February 2025