PHP TypeLang Help

Feature Toggling

You can enable or disable a set of parser features if your task requires only partial support of the functionality. This is convenient for implementing a stricter subset of the syntax — for example, allowing plain PHP type declarations while rejecting PHPStan/Psalm-style generics.

Configuring Features

All flags live on a single immutable value object, TypeLang\Parser\TypeParserFeatures, which is the first constructor argument of TypeParser. Every flag defaults to true.

use TypeLang\Parser\TypeParser; use TypeLang\Parser\TypeParserFeatures; $parser = new TypeParser(new TypeParserFeatures( literals: false, )); $parser->parse('42');
TypeLang\Parser\Exception\SemanticParseException: Literal values not allowed in "42" at column 1

To override one or more flags on an existing parser, use TypeParser::withFeatures() instead — it returns a new parser sharing everything else with the original one:

$parser = new TypeParser(); $strict = $parser->withFeatures( generics: false, shapes: false, );

TypeParserFeatures itself also has a with() method for deriving a new feature set from an existing one, keeping every flag not explicitly passed:

$features = new TypeParserFeatures() ->with(unions: false);

Available Features

Flag

Enables syntax

Error message fragment

literals

42, "foo", true, null, ...

Literal values not allowed

generics

Example<T>

Template arguments not allowed

hints

Example<out T, in U>

Template argument hints not allowed

lists

Example[]

Square bracket list types not allowed

offsets

Example[Type]

Type offsets not allowed

callables

fn(): void

Callable types not allowed

shapes

array{ key: T }

Shape fields not allowed

unions

T\|U

Union types not allowed

intersections

T&U

Intersection types not allowed

conditions

T is U ? A : B

Conditional expressions not allowed

attributes

#[attr] on fields/args/params

see below

Literals

Literals are concrete values such as 42, 0xDEAD, "string", 0.23, etc.

$parser = new TypeParser(new TypeParserFeatures( literals: false, )); $parser->parse('42');
Literal values not allowed in "42" at column 1

Generics

Template arguments (generics), i.e. the angle-bracket argument list of a named type.

$parser = new TypeParser(new TypeParserFeatures( generics: false, )); $parser->parse('Example<T>');
Template arguments not allowed in "Example<T>" at column 8

Hints

Template argument hints (variance modifiers) such as out/in.

$parser = new TypeParser(new TypeParserFeatures( hints: false, )); $parser->parse('Example<out T, U>');
Template argument hints not allowed in "Example<out T, U>" at column 9

Lists

The legacy square-bracket shorthand for iterable types.

$parser = new TypeParser(new TypeParserFeatures( lists: false, )); $parser->parse('Example[]');
Square bracket list types not allowed in "Example[]" at column 1

Offsets

Type offset access, i.e. reading the value type of key out of another type.

$parser = new TypeParser(new TypeParserFeatures( offsets: false, )); $parser->parse('Example[Type]');
Type offsets not allowed in "Example[Type]" at column 1

Callables

Callable (delegate) type declarations.

$parser = new TypeParser(new TypeParserFeatures( callables: false, )); $parser->parse('fn(): void');
Callable types not allowed in "fn(): void" at column 1

Shapes

Array/object shape fields.

$parser = new TypeParser(new TypeParserFeatures( shapes: false, )); $parser->parse(<<<'PHP' array{foo: T} PHP);
Shape fields not allowed in "array{foo: T}" on line 1 at column 6

Unions

$parser = new TypeParser(new TypeParserFeatures( unions: false, )); $parser->parse('T|U');
Union types not allowed in "T|U" at column 1

Intersections

$parser = new TypeParser(new TypeParserFeatures( intersections: false, )); $parser->parse('T&U');
Intersection types not allowed in "T&U" at column 1

Conditions

Conditional (ternary) type expressions, i.e. T is U ? A : B.

$parser = new TypeParser(new TypeParserFeatures( conditions: false, )); $parser->parse('T is U ? 23 : 42');
Conditional expressions not allowed in "T is U ? 23 : 42" at column 1

Attributes

Unlike the other flags, attributes is checked independently at every place attributes may occur — currently on shape fields, on template arguments, and on callable parameters — each reporting its own message.

$parser = new TypeParser(new TypeParserFeatures( attributes: false, )); $parser->parse(<<<'PHP' array{ #[name("new_name"), skip_when_empty] oldName: int, } PHP);
Shape field attributes not allowed in "array{\n #[name("new_name"), …" (33+) on line 2 at column 5
$parser->parse('Collection<#[a] T>');
Template argument attributes not allowed in "Collection<#[a] T>" at column 12
$parser->parse('callable(#[a] int $x): void');
Callable parameter attributes not allowed in "callable(#[a] int $x): void" at column 10
05 July 2026