PHP TypeLang Help

Type Printer Component

The printer component is the inverse of the parser: where the parser turns a type string into an AST, the printer turns that AST back into a string. It walks a TypeLang\Type\TypeNode and renders every node — a union, a shape, a conditional type — into readable text.

It ships with two printers that render the very same AST differently:

TypeLang\Printer\PrettyTypePrinter

Renders the type as faithfully as possible, preserving every detail the AST carries — shapes, generics, conditional types and all. See Pretty Printer.

TypeLang\Printer\NativeTypePrinter

Renders the closest type PHP itself would accept, collapsing anything without a native equivalent down to a supported approximation. See Native Printer.

Installation

Requirements:

  • PHP >= 8.4

  • ext-mbstring optional

Quick Start

Every printer implements TypeLang\Printer\TypePrinterInterface, a single print() method that takes a TypeNode and returns its string form. The AST usually comes straight from the parser, but any hand-built or rewritten TypeLang\Type\* node graph prints just as well.

use TypeLang\Parser\TypeParser; use TypeLang\Printer\PrettyTypePrinter; $type = new TypeParser()->parse('non-empty-list<positive-int>|null'); echo new PrettyTypePrinter()->print($type);
use TypeLang\Parser\TypeParser; use TypeLang\Printer\NativeTypePrinter; $type = new TypeParser()->parse('non-empty-list<positive-int>|null'); echo new NativeTypePrinter()->print($type);

Choosing a Printer

Both printers accept the same AST; they differ only in what they render.

Pretty

Native

Goal

faithful, human-readable

valid PHP syntax

array{id: int}

array{id: int}

array

int[]

int[]

iterable

positive-int

positive-int

int

Foo::BAR

Foo::BAR

mixed

int<0, max>

int<0, max>

int

$arg is null ? A : B

($arg is null ? A : B)

A│B

Reach for the pretty printer to display a type to a human — an error message, a generated docblock, a diff — where every detail matters. Reach for the native printer to emit something PHP can actually use — a property type, a parameter hint, generated code.

Formatting

Both printers share two constructor arguments, declared on the common TypeLang\Printer\TypePrinter base:

newLine

The line-break string inserted between the lines of a multi-line rendering. Defaults to "\n".

indention

The string used for a single indentation level. Defaults to four spaces.

$printer = new PrettyTypePrinter( newLine: "\r\n", indention: "\t", );

Error Handling

A printer only knows how to render the nodes that make up a valid type. If it is handed a node it cannot render — a malformed, hand-built AST, or a node kind it does not support — it throws a TypeLang\Printer\Exception\NonPrintableNodeException.

try { echo $printer->print($node); } catch (\TypeLang\Printer\Exception\PrinterExceptionInterface $e) { // Every exception the component throws implements this interface. }

An AST produced by the parser is always printable, so this only becomes a concern when constructing or rewriting the node graph by hand.

What's Next

Pretty Printer

The high-fidelity renderer and its formatting options — union and intersection spacing, callable return types, and multi-line shapes. See Pretty Printer.

Native Printer

The PHP-compatible renderer: how each unsupported construct is approximated, and the built-in and custom type aliases it applies. See Native Printer.

08 July 2026