The reference printer for TypeLang. It renders TypeLang\Type\* AST nodes
back into their string representation.
Two printers are provided:
NativeTypePrinter— outputs a valid, native PHP type declaration.PrettyTypePrinter— outputs the full PHPStan/Psalm-style type, formatted across multiple lines.
Full documentation is available at typelang.dev.
Install the package via Composer:
composer require type-lang/printerRequirements:
- PHP 8.1+
Parse a type into an AST (using type-lang/parser),
then print it back with either printer:
$parser = new TypeLang\Parser\TypeParser();
$type = $parser->parse(<<<'PHP'
array{
field1: (callable(Example, int): mixed),
field2: list<Some>,
...
}
PHP);
echo (new TypeLang\Printer\NativeTypePrinter())->print($type);
// array
echo (new TypeLang\Printer\PrettyTypePrinter())->print($type);
// array{
// field1: callable(Example, int): mixed,
// field2: list<Some>,
// ...
// }The formatting is set with the PrinterOptions:
use TypeLang\Printer\PrettyTypePrinter;
use TypeLang\Printer\PrinterOptions;
use TypeLang\Printer\PrinterOptions\CommaSpacing;
use TypeLang\Printer\PrinterOptions\ListStyle;
use TypeLang\Printer\PrinterOptions\NullableStyle;
use TypeLang\Printer\PrinterOptions\UnionSpacing;
$printer = new PrettyTypePrinter(new PrinterOptions(
unionSpacing: UnionSpacing::Spaced, // int | string
maxInlineTemplateItems: 2, // array<K, V> is written one argument per line after 2 of them
commaSpacing: CommaSpacing::Compact, // array<K,V>
nullableStyle: NullableStyle::Union, // int|null instead of ?int
listStyle: ListStyle::Generic, // array<int> instead of int[]
));Every kind of node is printed by its own NodePrinterInterface, and a printer
looks them up in a registry. To change how a node is printed, replace its
printer instead of extending the printer:
use TypeLang\Printer\NodePrinterInterface;
use TypeLang\Printer\PrettyTypePrinter;
use TypeLang\Printer\PrinterContext;
use TypeLang\Printer\TypePrinter;
use TypeLang\Type\NamedTypeNode;
use TypeLang\Type\Node;
/**
* @template-implements NodePrinterInterface<NamedTypeNode>
*/
final class ShoutingNamePrinter implements NodePrinterInterface
{
public function printNode(Node $node, PrinterContext $context): string
{
return \strtoupper($node->name->toString());
}
}
$printer = new TypePrinter(
PrettyTypePrinter::createRegistry()->with(NamedTypeNode::class, new ShoutingNamePrinter()),
);A node without its own printer is printed by the printer of the closest parent
class. The PrinterContext prints the children of a node ($context->print())
and carries the options.