Typing properties | typescript-transformer | Spatie

 SPATIE

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

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Typescript-transformer](https://spatie.be/docs/typescript-transformer/v2)  Dtos  Typing properties

 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                                                                                                                                                                                                                                    `

Typing properties
=================

###  On this page

1. [ Using PHP's built-in typed properties ](#content-using-phps-built-in-typed-properties)
2. [ Using attributes ](#content-using-attributes)
3. [ Using docblocks ](#content-using-docblocks)
4. [ Combining regular types and docblocks ](#content-combining-regular-types-and-docblocks)
5. [ Optional types ](#content-optional-types)
6. [ Hidden types ](#content-hidden-types)

Let's take a look at how we can type individual properties of a PHP class.

Using PHP's built-in typed properties
---------------------------------------------------------------------------------------------------------------------------------------------------------------------

It's possible to use typed properties in a class. This package makes these types an A-class citizen.

```
class Dto
{
    public string $string;

    public int $integer;

    public float $float;

    public bool $bool;

    public array $array;

    public mixed $mixed;
}
```

It is also possible to use nullable types:

```
class Dto
{
    public ?string $string;
}
```

You can even use these union types:

```
class Dto
{
    public float|int $float_or_int;
}
```

Or use other types that can be replaced:

```
class Dto
{
    public DateTime $datetime;
}
```

Using attributes
--------------------------------------------------------------------------------------------------------

You can use one of the two attributes provided by the package to transform them to TypeScript directly, more information about this [here](https://spatie.be/docs/typescript-transformer/v2/usage/annotations#using-typescript-within-php).

Using docblocks
-----------------------------------------------------------------------------------------------------

You can also use docblocks to type properties. You can find a more detailed overview of this [here](https://docs.phpdoc.org/guide/guides/types.html). While PHP's built-in typed properties are fine, docblocks allow for a bit more flexibility:

```
class Dto
{
    /** @var string */
    public $string;

    /** @var int */
    public $integer;

    /** @var float */
    public $float;

    /** @var bool */
    public $bool;

    /** @var array */
    public $array;

    /** @var array|string */
    public $arrayThatMightBeAString;
}
```

It is also possible to use nullable types in docblocks:

```
class Dto
{
    /** @var ?string */
    public $string;
}
```

And add types for your (custom) objects:

```
class Dto
{
    /** @var \DateTime */
    public $dateTime;
}
```

Note: always use the fully qualified class name (FQCN). At this moment, the package cannot determine imported classes used in a docblock:

```
use App\DataTransferObjects\UserData;

class Dto
{
    /** @var \App\DataTransferObjects\UserData */
    public $userData; // FCCN: this will work

    /** @var UserData */
    public $secondUserData; // Won't work, class import is not detected
}
```

It's also possible to add compound types:

```
class Dto
{
    /** @var string|int|bool|null */
    public $compound;
}
```

Or these unusual PHP specific types:

```
class Dto
{
    /** @var mixed */
    public $mixed; // transforms to `any`

    /** @var scalar */
    public $scalar; // transforms to `string|number|boolean`

    /** @var void */
    public $void; // transforms to `never`
}
```

You can even reference the object's own type:

```
class Dto
{
    /** @var self */
    public $self;

    /** @var static */
    public $static;

    /** @var $this */
    public $void;
}
```

These will all transform to a `Dto` TypeScript type.

### Transforming arrays

Arrays in PHP and TypeScript (JavaScript) are entirely different concepts. This poses a couple of problems we'll address. A PHP array is a multi-use storage/memory structure. In TypeScript, a PHP array can be represented both as an `Array` and as an `Object` with specified keys.

Depending on how your annotations are written, the package will output either an `Array` or `Object`. Let's have a look at some examples that will transform into an `Array` type:

```
class Dto
{
    /** @var \DateTime[] */
    public $array;

    /** @var array */
    public $another_array;

    /** @var array */
    public $you_probably_wont_write_this;
}
```

You can type objects as such:

```
class Dto
{
    /** @var array */
    public $object_with_string_keys;

    /** @var array */
    public $object_with_int_keys;
}
```

Combining regular types and docblocks
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Whenever a property has a docblock, that docblock will be used to type the property. The 'real' PHP type will be omitted.

If the property is nullable and has a docblock that isn't nullable, then the package will make the TypeScript type nullable.

Optional types
--------------------------------------------------------------------------------------------------

You can make certain properties of a DTO optional in TypeScript as such:

```
class DataObject extends Data
{
    public function __construct(
        #[Optional]
        public int $id,
        public string $name,
    )
    {
    }
}
```

This will be transformed into:

```
{
    id? : number;
    name : string;
}
```

You can also transform all properties in a class to optional, by adding the attribute to the class:

```
#[Optional]
class DataObject extends Data
{
    public function __construct(
        public int $id,
        public string $name,
    )
    {
    }
}
```

Now all properties will be optional:

```
{
    id? : number;
    name? : string;
}
```

Hidden types
--------------------------------------------------------------------------------------------

You can make certain properties of a DTO hidden in TypeScript as such:

```
class DataObject extends Data
{
    public function __construct(
        public int $id,
        #[Hidden]
        public string $hidden,
    )
    {
    }
}
```

This will be transformed into:

```
{
    id : number;
}
```
