Describing types | typescript-transformer | Spatie

 SPATIE

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

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Typescript-transformer](https://spatie.be/docs/typescript-transformer/v2)  Usage  Describing types

 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                                                                                                                                                                                                                                    `

Describing types
================

###  On this page

1. [ Inlining types ](#content-inlining-types)
2. [ Using TypeScript to write TypeScript ](#content-using-typescript-to-write-typescript)
3. [ Using PHP types to write TypeScript ](#content-using-php-types-to-write-typescript)
4. [ Generating ](#content-generating-record-types)
5. [ Selecting a transformer ](#content-selecting-a-transformer)

PHP classes will only be converted to TypeScript when they are annotated, there are quite a few ways to do this, let's take a look.

When using the `@typescript` annotation, the PHP class's name will be used as name for the TypeScript type:

```
/** @typescript */
class Language extends Enum{
    const en = 'en';
    const nl = 'nl';
    const fr = 'fr';
}
```

The package will produce the following TypeScript:

```
export type Language = 'en' | 'nl' | 'fr';
```

It is also possible to use a PHP8 attribute like this:

```
#[TypeScript]
class Language extends Enum{
    const en = 'en';
    const nl = 'nl';
    const fr = 'fr';
}
```

You can also give the type another name:

```
/** @typescript Talen **/
class Language extends Enum{}
```

Which also can be done using attributes:

```
#[TypeScript('Talen')]
class Language extends Enum{}
```

Now the transformed TypeScript looks like this:

```
export type Talen = 'en' | 'nl' | 'fr';
```

Inlining types
--------------------------------------------------------------------------------------------------

It is also possible to annotate types as an inline type. These types will not create a whole new TypeScript type but replace a type inline in another type. Let's create a class containing the `Language` enum:

```
/** @typescript **/
class Post
{
    public string $name;
    public Language $language;
}
```

The transformed version of a `Post` would look like this:

```
export type Language = 'en' | 'nl' | 'fr';

export type Post = {
    name : string;
    language : Language;
}
```

We could inline the `Language` enum as such:

```
/**
 * @typescript
 * @typescript-inline
 */
class Language extends Enum{}
```

Or using an attribute:

```
#[TypeScript]
#[InlineTypeScriptType]
class Language extends Enum{}
```

And now our transformed TypeScript would look like this:

```
export type Post = {
    name : string;
    language : 'en' | 'nl' | 'fr';
}
```

Using TypeScript to write TypeScript
--------------------------------------------------------------------------------------------------------------------------------------------------------------------

It is possible to directly represent a type as TypeScript within your PHP code:

```
#[TypeScript]
#[LiteralTypeScriptType("string | null")]
class CustomString{}
```

Now when `Language` is being transformed, the TypeScript representation is used:

```
export type CustomString = string | null;
```

You can even provide an array of types:

```
#[TypeScript]
#[LiteralTypeScriptType([
    'email' => 'string',
    'name' => 'string',
    'age' => 'number',
])]
class UserData{
    public $email;
    public $name;
    public $age;
}
```

This would transform to:

```
export type UserData = {
    email: string;
    name: string;
    age: number;
};
```

This attribute can also be used with properties in a class, for example:

```
#[TypeScript]
class Post
{
    public string $name;

    #[LiteralTypeScriptType("'en' | 'nl' | 'fr'")]
    public Language $language;
}
```

Using PHP types to write TypeScript
-----------------------------------------------------------------------------------------------------------------------------------------------------------------

When you have a very specific type you want to describe in PHP then you can use the `TypeScriptType` which can transform every type [phpdocumentor](https://www.phpdoc.org) can read. For example, let's say you have an array that always has the same keys as this one:

```
$user = [
    'name' => 'Ruben Van Assche',
    'email' => 'ruben@spatie.be',
    'age' => 26,
    'language' => Language::nl()
];
```

When we put that array as a property in a class:

```
#[TypeScript]
class UserRepository{
    public array $user;
}
```

The transformed type will look like this:

```
export type UserRepository = {
    user: Array;
};
```

We can do better than this, since we know the keys of the array:

```
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript]
class UserRepository{
    #[TypeScriptType([
        'name' => 'string',
        'email' => 'string',
        'age' => 'int',
        'language' => Language::class
    ])]
    public array $user;
}
```

Now the transformed TypeScript will look like this:

```
export type UserRepository = {
    user: {
        name: string;
        email: string;
        age: number;
        language: 'en' | 'nl' | 'fr';
    };
};
```

As you can see, the package is smart enough to convert `Language::class` to an inline enum we defined earlier.

Generating `Record` types
-------------------------------------------------------------------------------------------------------------------------------

If you need to generate a `Record` type, you may use the `RecordTypeScriptType` attribute:

```
use Spatie\TypeScriptTransformer\Attributes\RecordTypeScriptType;

class FleetData extends Data
{
    public function __construct(
        #[RecordTypeScriptType(AircraftType::class, AircraftData::class)]
        public readonly array $fleet,
    ) {
    }
}
```

This will generate a `Record` type with a key type of `AircraftType::class` and a value type of `AircraftData::class`:

```
export type FleetData = {
  fleet: Record
}
```

Additionally, if you need the value type to be an array of the specified type, you may set the third parameter of `RecordTypeScriptType` to `true`:

```
class FleetData extends Data
{
    public function __construct(
        #[RecordTypeScriptType(AircraftType::class, AircraftData::class, array: true)]
        public readonly array $fleet,
    ) {
    }
}
```

This will generate the following interface:

```
export type FleetData = {
  fleet: Record
}
```

Selecting a transformer
-----------------------------------------------------------------------------------------------------------------------------

Want to define a specific transformer for the file? You can use the following annotation:

```
/**
 * @typescript
 * @typescript-transformer \Spatie\TypeScriptTransformer\Transformers\SpatieEnumTransformer::class
 */
class Languages extends Enum{}
```

It is also possible to transform types without adding annotations. You can read more about it [here](https://spatie.be/docs/typescript-transformer/v2/usage/selecting-classes-using-collectors).
