spatie / laravel-typescript-transformer
Transform your PHP structures to TypeScript types
Fund package maintenance!
spatie
spatie.be/open-source/support-us
Installs: 5 190 521
Dependents: 46
Suggesters: 3
Security: 0
Stars: 355
Watchers: 5
Forks: 25
Open Issues: 1
pkg:composer/spatie/laravel-typescript-transformer
Requires
- php: ^8.1
- illuminate/contracts: ^11.0|^12.0
- spatie/typescript-transformer: dev-main
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- pestphp/pest: ^3.0|^4.2
- pestphp/pest-plugin-arch: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^2.0
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-data: ^4.0
- spatie/pest-plugin-snapshots: ^2.1
README
Transform PHP to TypeScript
This package allows you to convert PHP classes and more to TypeScript.
This class...
#[TypeScript] class User { public int $id; public string $name; public ?string $address; }
... will be converted to this TypeScript type:
export type User = { id: number; name: string; address: string | null; }
Here's another example.
enum Languages: string { case TYPESCRIPT = 'typescript'; case PHP = 'php'; }
The Languages enum will be converted to:
export type Languages = 'typescript' | 'php';
And that's just the beginning! TypeScript transformer can handle complex types, generics and even allows you to create TypeScript functions.
Installation
You can install the package via composer:
composer require spatie/laravel-typescript-transformer
Setting up TypeScript transformer
When using Laravel, first install the specific TypeScriptTransformerServiceProvider:
php artisan typescript:install
This command will create a TypeScriptTransformerServiceProvider in your app/Providers directory. Which looks like
this:
class TypeScriptTransformerServiceProvider extends BaseTypeScriptTransformerServiceProvider { protected function configure(TypeScriptTransformerConfigFactory $config): void { $config; // We'll come back to this in a minute } }
And it will also register the service provider in your bootstrap/providers.php file (when running Laravel 11 or
above). Or in your config/app.php file when running Laravel 10 or below.
Now you can transform types as such:
php artisan typescript:transform
Since we haven't configured TypeScript transformer yet, this command won't do anything.
In order to configure TypeScript Transformer, we recommand you to now continue reading the documentation on the
framework-agnostic typescript-transformer package. The docs will
explain how to configure the package which is by modifying the $config object we saw earlier in the
TypeScriptTransformerServiceProvider.
After you're done reading the framework-agnostic docs, you can return here to read about Laravel-specific features this package provides.
Watching changes and live updating TypeScript
It is possible to have TypeScript transformer watch your PHP files for changes and automatically update the generated TypeScript files. You can do this by running:
php artisan typescript:transform --watch
Laravel-specific features
This package provides some extra features on top of the base TypeScript transformer package tailed for Laravel applications. Let's go through them.
Your routes in TypeScript
Laravel provides a great way to define routes and then generate URLs to those routes in PHP using the route() helper.
While this all works in PHP, it can be a bit of a pain to do the same in TypeScript. TypeScript transformer can help you
here by providing exact copy of the route() helper in TypeScript.
To add the helper, add the following provider to your TypeScriptTransformerServiceProvider:
use Spatie\LaravelTypeScriptTransformer\TransformedProviders\LaravelRouteTransformedProvider; protected function configure(TypeScriptTransformerConfigFactory $config): void { $config->provider(new LaravelRouteTransformedProvider()); }
The next time you run the typescript:transform command, a TypeScript function called route will be generated in
the helpers/route.ts file.
You can now use the route function in your TypeScript code like this:
import {route} from './helpers/route'; // Without parameters const indexUrl = route('users.index'); // https://laravel.dev/users // With parameters const userUrl = route('users.show', {user: 1}); // https://laravel.dev/users/1
TypeScript will be smart enough to provide you autocompletion on these controllers and their parameters.
Sometimes you might want to exclude certain routes from being included in the generated TypeScript. You can do this by adding a route filter. The package provides three types of route filters:
NamedRouteFilter
Allows you to remove routes by their name. It is possible to use wildcards.
use Spatie\LaravelTypeScriptTransformer\RouteFilters\NamedRouteFilter; $config->provider(new LaravelRouteTransformedProvider( routeFilters: [ new NamedRouteFilter('debugbar.*', 'hidden'), ], ));
ControllerRouteFilter
Allows you to remove routes by their controller class or namespace using wildcards.
use Spatie\LaravelTypeScriptTransformer\RouteFilters\ControllerRouteFilter; $config->provider(new LaravelRouteTransformedProvider( routeFilters: [ new ControllerRouteFilter(['App\Http\Controllers\Admin\*', 'HiddenController']), ], ));
ClosureRouteFilter
Allows you to provide a closure that will be called for each route. If the closure returns true, the route will be
excluded.
use Spatie\LaravelTypeScriptTransformer\RouteFilters\ClosureRouteFilter; $config->provider(new LaravelRouteTransformedProvider( routeFilters: [ new ClosureRouteFilter(function (Route $route) { return str_starts_with($route->uri(), 'internal/'); }), ], ));
By default, the helper will generate absolute URLs meaning it includes the app URL. This URL will be fetched from the
window object in JavaScript. If you want to generate relative URLs instead, you can pass false as the third parameter,
indicating you don't want absolute URLs:
const indexUrl = route('users.index', {}, false); // /users
The default value of the absolute parameter can be changed by setting a default for the provider:
$config->provider(new LaravelRouteTransformedProvider( absoluteUrlsByDefault: false, ));
Now when using the route helper in TypeScript, URLs will be relative by default:
const indexUrl = route('users.index'); // /users
TypeScript transformer will automatically generate the helpers/route.ts file in the output directory you configured
for TypeScript transformer. It is possible to change the path of this file as such:
$config->provider(new LaravelRouteTransformedProvider( path: 'route.ts', ));
When running in the watch mode of the package, the generated route.ts file will automatically be updated when you
change your routes in Laravel. By default the watcher will monitor the following directories for changes:
routesbootstrapapp/Providers
It is possible to customize the directories that are monitored as such:
$config->provider(new LaravelRouteTransformedProvider( routeDirectories: [ 'custom/routes/directory', 'another/directory/to/watch', ], )); ## Testing ``` bash composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security
If you've found a bug regarding security please mail security@spatie.be instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.