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"

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>, callable<T>(T): 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

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"

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>"

The same flag closes the other side of the angle brackets: the template parameters a callable declares.

$parser->parse('callable<T>(T): T');
Template parameters not allowed in "callable<T>(T): T"

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>"

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[]"

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]"

Callables

Callable (delegate) type declarations.

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

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}"

Unions

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

Intersections

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

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"
12 September 2026