Under the hood | typescript-transformer | Spatie

 SPATIE

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

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Typescript-transformer](https://spatie.be/docs/typescript-transformer/v2)  Under the hood

 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                                                                                                                                                                                                                                    `

Under the hood
==============

###  On this page

1. [ Step 0: configuring the package ](#content-step-0-configuring-the-package)
2. [ Step 1: Collecting classes ](#content-step-1-collecting-classes)
3. [ Step 2: Transforming classes ](#content-step-2-transforming-classes)
4. [ Step 3: Replacing missing symbols ](#content-step-3-replacing-missing-symbols)
5. [ Step 4: persisting types ](#content-step-4-persisting-types)
6. [ Step 5: formatting the output ](#content-step-5-formatting-the-output)

Reading this page is not required for knowing how to use the package. We recommend to first read through the other documentation and then come back to read this page.

Step 0: configuring the package
---------------------------------------------------------------------------------------------------------------------------------------------------

In the package configuration a couple important values are defined:

- the path where your PHP classes are stored,
- the file where the TypeScript definition will be written,
- the collectors that will find relevant PHP classes that can be transformed,
- and the transformers required to convert PHP to TypeScript.

Step 1: Collecting classes
------------------------------------------------------------------------------------------------------------------------------------

We start by iterating over the PHP classes in the specified directory and create a `ReflectionClass` for each class. If a collector can collect one of these classes, it will try to find a suitable transformer.

For example, the `DefaultCollector` will collect each class with a `@typescript` annotation or a `#[TypeScript]` attribute and feed it to all the registered transformers to hopefully find a transformer that can generate a type definition for the class.

Step 2: Transforming classes
------------------------------------------------------------------------------------------------------------------------------------------

We've created a set of classes and their suitable transformers in step 1. We're now going to transform these types to TypeScript. For the enum example, this is relatively simple, but for a complex data transfer object (DTO) this process is a bit more complicated.

Each property of the DTO will be checked: does it have a PHP type and/or does it have an annotated type? The package creates a unified `Type` from this and feeds it to the type processors. These will transform the type or completely remove it from the DTO's TypeScript definition.

A good example of a type processor is the `ReplaceDefaultsTypeProcessor`. This one will replace some default types you can define in the configuration with a TypeScript representation. For example transforming `DateTime` or `Carbon` types to `string`.

DTO's often have properties that contain other DTO's, or even other custom types. This is why we'll also keep track of the missing symbols when transforming a DTO. Let's say your DTO has a property that contains another DTO. At the moment of transformation, the package will not know how that other DTO should be transformed. We'll temporarily use a missing symbol that can be replaced by a reference to the correct DTO type later.

Step 3: Replacing missing symbols
---------------------------------------------------------------------------------------------------------------------------------------------------------

The classes we started with in step 2 are now transformed into TypeScript definitions, although some types are still missing references to other types. Thanks to the missing symbols collections that each transformer constructed, we can replace these references with the correct type.

If a reference cannot be replaced because it cannot be found the package will default to the `any` type, as it doesn't know how to reference it.

It's recommended to try to avoid these `any` types as much as possible.

Step 4: persisting types
------------------------------------------------------------------------------------------------------------------------------

Our set of transformed classes is now ready. All missing symbols are replaced, so it's time to write them out. A writer will take the entire set of transformed types and write them down into a TypeScript type defintion file you configured.

Step 5: formatting the output
---------------------------------------------------------------------------------------------------------------------------------------------

The package tries to output readable TypeScript code without adhering to any code style. Using tools like Prettier the output can be formatted in a code style of your choice.
