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/v1)  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/v1/introduction)
- [ Postcardware ](https://spatie.be/docs/typescript-transformer/v1/postcardware)
- [ Installation ](https://spatie.be/docs/typescript-transformer/v1/installation)
- [ Under the hood ](https://spatie.be/docs/typescript-transformer/v1/under-the-hood)
- [ Questions &amp; issues ](https://spatie.be/docs/typescript-transformer/v1/questions-and-issues)
- [ Changelog ](https://spatie.be/docs/typescript-transformer/v1/changelog)
- [ About us ](https://spatie.be/docs/typescript-transformer/v1/about-us)

Usage
-----

- [ General overview ](https://spatie.be/docs/typescript-transformer/v1/usage/general-overview)
- [ Getting started ](https://spatie.be/docs/typescript-transformer/v1/usage/getting-started)
- [ Using transformers ](https://spatie.be/docs/typescript-transformer/v1/usage/using-transformers)
- [ Customizing the output using annotations ](https://spatie.be/docs/typescript-transformer/v1/usage/annotations)
- [ Selecting classes using collectors ](https://spatie.be/docs/typescript-transformer/v1/usage/selecting-classes-using-collectors)

Dto's
-----

- [ Transforming DTOs ](https://spatie.be/docs/typescript-transformer/v1/dtos/transforming-dtos)
- [ Typing properties ](https://spatie.be/docs/typescript-transformer/v1/dtos/typing-properties)
- [ Changing types using class property processors ](https://spatie.be/docs/typescript-transformer/v1/dtos/changing-types-with-class-property-processors)

Laravel
-------

- [ Installation and setup ](https://spatie.be/docs/typescript-transformer/v1/laravel/installation-and-setup)
- [ Executing the transform command ](https://spatie.be/docs/typescript-transformer/v1/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)

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 transformers required to convert PHP to TypeScript,
- and the collectors that will find relevant PHP classes that can be transformed.

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 `AnnotationCollector` will collect each class with a `@typescript` annotation 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 class property processors. These will transform the type or completely remove it from the DTO's TypeScript definition.

A good example of a class property processor is the `ReplaceDefaultTypesClassPropertyProcessor`. 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 correcty 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 for the last step. We'll take the entire set of transformed types and write them down into a TypeScript type defintion file you configured.
