Skip to content

TypeScript Generation

Learn how to automatically generate TypeScript types from your DTOs.

SimpleDTO can automatically generate TypeScript interfaces and types from your PHP DTOs:

  • Automatic Generation - Generate TypeScript from PHP
  • Type Mapping - PHP types → TypeScript types
  • Nested DTOs - Automatic nested type generation
  • Enums - PHP enums → TypeScript enums
  • Arrays & Collections - Proper array typing
  • Optional Properties - Nullable → optional
  • JSDoc Comments - Include PHP docblocks
Terminal window
php artisan dto:typescript
Terminal window
bin/console dto:typescript
use event4u\DataHelpers\SimpleDTO\TypeScript\Generator;
$generator = new Generator();
$generator->generate(
dtoPath: __DIR__ . '/src/DTO',
outputPath: __DIR__ . '/frontend/types'
);
class UserDTO extends SimpleDTO
{
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly string $email,
public readonly ?string $phone = null,
) {}
}
export interface UserDTO {
id: number;
name: string;
email: string;
phone?: string | null;
}
// PHP
public readonly string $name;
public readonly int $age;
public readonly float $price;
public readonly bool $active;
// TypeScript
name: string;
age: number;
price: number;
active: boolean;
// PHP
public readonly array $tags;
/** @var string[] */
public readonly array $categories;
// TypeScript
tags: any[];
categories: string[];
// PHP
public readonly ?string $middleName = null;
public readonly ?int $age = null;
// TypeScript
middleName?: string | null;
age?: number | null;
// PHP
public readonly string|int $id;
// TypeScript
id: string | number;
class AddressDTO extends SimpleDTO
{
public function __construct(
public readonly string $street,
public readonly string $city,
public readonly string $country,
) {}
}
class UserDTO extends SimpleDTO
{
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly AddressDTO $address,
) {}
}
export interface AddressDTO {
street: string;
city: string;
country: string;
}
export interface UserDTO {
id: number;
name: string;
address: AddressDTO;
}
class PostDTO extends SimpleDTO
{
public function __construct(
public readonly int $id,
public readonly string $title,
/** @var CommentDTO[] */
public readonly array $comments,
) {}
}
class CommentDTO extends SimpleDTO
{
public function __construct(
public readonly int $id,
public readonly string $content,
) {}
}
export interface CommentDTO {
id: number;
content: string;
}
export interface PostDTO {
id: number;
title: string;
comments: CommentDTO[];
}
enum UserRole: string
{
case ADMIN = 'admin';
case USER = 'user';
case GUEST = 'guest';
}
class UserDTO extends SimpleDTO
{
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly UserRole $role,
) {}
}
export enum UserRole {
ADMIN = 'admin',
USER = 'user',
GUEST = 'guest',
}
export interface UserDTO {
id: number;
name: string;
role: UserRole;
}
config/simple-dto.php
return [
'typescript' => [
'output' => resource_path('js/types/dtos.ts'),
'export_type' => 'export', // 'export', 'declare', or ''
'include_comments' => true,
'sort_properties' => false,
],
];
config/packages/simple_dto.yaml
simple_dto:
typescript:
output: '%kernel.project_dir%/assets/types/dtos.ts'
export_type: 'export'
include_comments: true
sort_properties: false
Terminal window
php artisan dto:typescript --watch
Terminal window
bin/console dto:typescript --watch

Automatically regenerates TypeScript when DTOs change.

Terminal window
# Laravel
php artisan dto:typescript --check
# Symfony
bin/console dto:typescript --check

Returns exit code 1 if types are outdated.

name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: composer install
- name: Check TypeScript types
run: php artisan dto:typescript --check
// ✅ Good
public readonly string $name;
// ❌ Bad - generates 'any'
public readonly $name;
// ✅ Good
/** @var string[] */
public readonly array $tags;
// ❌ Bad - generates 'any[]'
public readonly array $tags;
// ✅ Good
public readonly UserRole $role;
// ❌ Bad
public readonly string $role;
Terminal window
# Add to deployment script
php artisan dto:typescript

The following working examples demonstrate this feature:

All examples are fully tested and can be run directly.

The functionality is thoroughly tested. Key test files:

Run the tests:

Terminal window
# Run tests
task test:unit -- --filter=TypeScript