Type processors | typescript-transformer | Spatie

 SPATIE

  TypeScript Transformer
=========================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Typescript-transformer](https://spatie.be/docs/typescript-transformer/v2)  Transformers  Type processors

 Version   v3   v2   v1

 Other versions for crawler [v3](https://spatie.be/docs/typescript-transformer/v3) [v2](https://spatie.be/docs/typescript-transformer/v2) [v1](https://spatie.be/docs/typescript-transformer/v1)

- [ Introduction ](https://spatie.be/docs/typescript-transformer/v2/introduction)
- [ Postcardware ](https://spatie.be/docs/typescript-transformer/v2/postcardware)
- [ Installation ](https://spatie.be/docs/typescript-transformer/v2/installation)
- [ Under the hood ](https://spatie.be/docs/typescript-transformer/v2/under-the-hood)
- [ Questions &amp; issues ](https://spatie.be/docs/typescript-transformer/v2/questions-and-issues)
- [ Changelog ](https://spatie.be/docs/typescript-transformer/v2/changelog)
- [ About us ](https://spatie.be/docs/typescript-transformer/v2/about-us)

Usage
-----

- [ General overview ](https://spatie.be/docs/typescript-transformer/v2/usage/general-overview)
- [ Getting started ](https://spatie.be/docs/typescript-transformer/v2/usage/getting-started)
- [ Describing types ](https://spatie.be/docs/typescript-transformer/v2/usage/annotations)
- [ Using transformers ](https://spatie.be/docs/typescript-transformer/v2/usage/using-transformers)
- [ Collectors ](https://spatie.be/docs/typescript-transformer/v2/usage/selecting-classes-using-collectors)
- [ Writers ](https://spatie.be/docs/typescript-transformer/v2/usage/writers)
- [ Formatters ](https://spatie.be/docs/typescript-transformer/v2/usage/formatters)

Writing transformers
--------------------

- [ Getting started ](https://spatie.be/docs/typescript-transformer/v2/transformers/getting-started)
- [ Type reflectors ](https://spatie.be/docs/typescript-transformer/v2/transformers/type-reflectors)
- [ Type processors ](https://spatie.be/docs/typescript-transformer/v2/transformers/type-processors)

Transforming PHP classes
------------------------

- [ Typing properties ](https://spatie.be/docs/typescript-transformer/v2/dtos/typing-properties)
- [ Customization ](https://spatie.be/docs/typescript-transformer/v2/dtos/transforming-dtos)

Laravel
-------

- [ Installation and setup ](https://spatie.be/docs/typescript-transformer/v2/laravel/installation-and-setup)
- [ Executing the transform command ](https://spatie.be/docs/typescript-transformer/v2/laravel/executing-the-transform-command)

      You are viewing the documentation for **an older version** of this package. You can check the version you are using with the following command:

 `                                    composer show spatie/typescript-transformer                                                                                                                                                                                                                                    `

Type processors
===============

###  On this page

1. [ Default type processors ](#content-default-type-processors)
2. [ Using type processors in your transformers ](#content-using-type-processors-in-your-transformers)
3. [ Writing type processors ](#content-writing-type-processors)

You can use type processors to change an entity's internal `Type` before it is transpiled into TypeScript.

Default type processors
-----------------------------------------------------------------------------------------------------------------------------

- `ReplaceDefaultsTypeProcessor` replaces some types defined in the configuration
- `DtoCollectionTypeProcessor` replaces `DtoCollections` from the `spatie/data-transfer-object` package with their TypeScript equivalent

Specifically for Laravel, we also include the following type processors in the Laravel package:

- `LaravelCollectionTypeProcessor` handles Laravel's `Collection` classes like `array`s

Using type processors in your transformers
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

When you're using the `TransformsTypes` [trait](https://github.com/spatie/typescript-transformer/blob/master/src/Transformers/TransformsTypes.php) in your transformer and use the `reflectionToTypeScript` then you can additionally pass type processors:

```
$this->reflectionToTypeScript(
    $reflection,
    $missingSymbolsCollection,
    new ReplaceDefaultsTypeProcessor(),
    new DtoCollectionTypeProcessor(),
    // and so on ...
);
```

Writing type processors
-----------------------------------------------------------------------------------------------------------------------------

A class property processor is any class that implements the `ClassPropertyProcessor` interface:

```
class MyClassPropertyProcessor implements TypeProcessor
{
    public function process(
        Type $type,
        ReflectionProperty|ReflectionParameter|ReflectionMethod $reflection,
        MissingSymbolsCollection $missingSymbolsCollection
    ): ?Type
    {
        // Transform the types of the property
    }
}
```

### Returning a type

You can either return a PHPDocumenter type or a `TypeScriptType` instance for literal TypeScript types.

Let's take a look at an example. With this type processor, it will convert each property type into a `string`.

Using a `TypeScriptType`:

```
class MyClassPropertyProcessor implements TypeProcessor
{
    public function process(
        Type $type,
        ReflectionProperty|ReflectionParameter|ReflectionMethod $reflection,
        MissingSymbolsCollection $missingSymbolsCollection
    ): ?Type
    {
        return TypeScriptType::create('SomeGenericType');
    }
}
```

Or using a PHPDocumenter type:

```
class MyClassPropertyProcessor implements TypeProcessor
{
    public function process(
        Type $type,
        ReflectionProperty|ReflectionParameter|ReflectionMethod $reflection,
        MissingSymbolsCollection $missingSymbolsCollection
    ): ?Type
    {
        return new String_();
    }
}
```

You can find all the possible PHPDocumenter types [here](https://github.com/phpDocumentor/TypeResolver/tree/1.x/src/Types).

### Walking over types

Since any type can exist of arrays, compound types, nullable types, and more, you'll sometimes need to walk (or loop) over these types to specify types case by case. This can be done by including the `ProcessesTypes` trait into your type processor.

This trait will add a `walk` method that takes an initial type and closure.

Let's say you have a compound type like `string|bool|int`. The `walk` method will run a `string`, `bool` and `int` type through the closure. You can then decide a type to be returned for each type given to the closure. Finally, the updated compound type will also be passed to the closure.

You can remove a type by returning `null`.

Let's take a look at an example where we only keep `string` types and remove any others:

```
class MyClassPropertyProcessor implements TypeProcessor
{
    use ProcessesTypes;

    public function process(
        Type $type,
        ReflectionProperty|ReflectionParameter|ReflectionMethod $reflection,
        MissingSymbolsCollection $missingSymbolsCollection
    ): ?Type
    {
        return $this->walk($type, function (Type $type) {
            if ($type instanceof _String || $type instanceof Compound) {
                return $type;
            }

            return null;
        });
    }
}
```

As you can see, we check in the closure if the type is a `string` or a `compound` type. If it is none of these two types, we remove it by returning `null`.

Why checking if the given type is a compound type? In the end, the compound type will be given to the closure. If we removed it, the whole property could be removed from the TypeScript definition.
