1- <div align =" left " >
2- <a href="https://spatie.be/open-source?utm_source=github&utm_medium=banner&utm_campaign=laravel-typescript-transformer">
3- <picture>
4- <source media="(prefers-color-scheme: dark)" srcset="https://spatie.be/packages/header/laravel-typescript-transformer/html/dark.webp?1744124203">
5- <img alt="Logo for laravel-typescript-transformer" src="https://spatie.be/packages/header/laravel-typescript-transformer/html/light.webp?1744124203">
6- </picture>
7- </a>
1+ [ <img src =" https://github-ads.s3.eu-central-1.amazonaws.com/support-ukraine.svg?t=1 " />] ( https://supportukrainenow.org )
82
9- < h1 > Transform PHP types to TypeScript</ h1 >
3+ # Transform PHP types to TypeScript
104
115[ ![ Latest Version on Packagist] ( https://img.shields.io/packagist/v/spatie/laravel-typescript-transformer.svg?style=flat-square )] ( https://packagist.org/packages/spatie/laravel-typescript-transformer )
126[ ![ GitHub Tests Action Status] ( https://img.shields.io/github/workflow/status/spatie/laravel-typescript-transformer/run-tests?label=tests )] ( https://github.com/spatie/laravel-typescript-transformer/actions?query=workflow%3Arun-tests+branch%3Amaster )
137[ ![ Styling] ( https://github.com/spatie/laravel-typescript-transformer/workflows/Check%20&%20fix%20styling/badge.svg )] ( https://github.com/spatie/laravel-typescript-transformer/actions?query=workflow%3A%22Check+%26+fix+styling%22 )
148[ ![ Psalm] ( https://github.com/spatie/laravel-typescript-transformer/workflows/Psalm/badge.svg )] ( https://github.com/spatie/laravel-typescript-transformer/actions?query=workflow%3APsalm )
159[ ![ Total Downloads] ( https://img.shields.io/packagist/dt/spatie/laravel-typescript-transformer.svg?style=flat-square )] ( https://packagist.org/packages/spatie/laravel-typescript-transformer )
16-
17- </div >
1810
19- Always wanted type safety within PHP and TypeScript without duplicating a lot of code? Then you will like this package! Let's say you have an enum:
11+ A
12+ This package allows you to convert PHP classes to TypeScript.
13+
14+ This class...
2015
2116``` php
22- class Languages extends Enum
17+ #[TypeScript]
18+ class User
2319{
24- const TYPESCRIPT = 'typescript';
25- const PHP = 'php';
20+ public int $id;
21+ public string $name;
22+ public ?string $address;
2623}
2724```
2825
29- Wouldn't it be cool if you could have an automatically generated TypeScript definition like this :
26+ ... will be converted to this TypeScript type :
3027
3128``` ts
32- export type Languages = ' typescript' | ' php' ;
29+ export type User = {
30+ id: number ;
31+ name: string ;
32+ address: string | null ;
33+ }
3334` ` `
3435
35- This package will automatically generate such definitions for you, the only thing you have to do is adding this annotation:
36+ Here's another example.
3637
3738` ` ` php
38- /** @typescript **/
39- class Languages extends Enum
39+ enum Languages : string
4040{
41- const TYPESCRIPT = 'typescript';
42- const PHP = 'php';
41+ case TYPESCRIPT = ' typescript' ;
42+ case PHP = ' php' ;
4343}
4444```
4545
46- You can even take it a bit further and generate TypeScript from classes:
46+ The ` Languages ` enum will be converted to:
47+
48+ ``` tsx
49+ export type Languages = ' typescript' | ' php' ;
50+ ```
51+
52+ And that's just the beginning! TypeScript transformer can handle complex types, generics and even allows you to create
53+ TypeScript functions.
54+
55+ ## Installation
56+
57+ You can install the package via composer:
58+
59+ ``` bash
60+ composer require spatie/laravel-typescript-transformer
61+ ```
62+
63+ ## Setting up TypeScript transformer
64+
65+ When using Laravel, first install the specific ` TypeScriptTransformerServiceProvider ` :
66+
67+ ``` bash
68+ php artisan typescript:install
69+ ```
70+
71+ This command will create a ` TypeScriptTransformerServiceProvider ` in your ` app/Providers ` directory. Which looks like
72+ this:
4773
4874``` php
49- /** @typescript */
50- class User
75+ class TypeScriptTransformerServiceProvider extends BaseTypeScriptTransformerServiceProvider
5176{
52- public int $id;
77+ protected function configure(TypeScriptTransformerConfigFactory $config): void
78+ {
79+ $config; // We'll come back to this in a minute
80+ }
81+ }
82+ ```
5383
54- public string $name;
84+ And it will also register the service provider in your ` bootstrap/providers.php ` file (when running Laravel 11 or
85+ above). Or in your ` config/app.php ` file when running Laravel 10 or below.
5586
56- public ?string $address;
87+ Now you can transform types as such:
88+
89+ ``` bash
90+ php artisan typescript:transform
91+ ```
92+
93+ Since we haven't configured TypeScript transformer yet, this command won't do anything.
94+
95+ In order to configure TypeScript Transformer, we recommand you to now continue reading the documentation on the
96+ framework-agnostic [ typescript-transformer] ( https://github.com/spatie/typescript-transformer ) package. The docs will
97+ explain how to configure the package which is by modifying the ` $config ` object we saw earlier in the
98+ ` TypeScriptTransformerServiceProvider ` .
99+
100+ After you're done reading the framework-agnostic docs, you can return here to read about Laravel-specific features this
101+ package provides.
102+
103+ ## Watching changes and live updating TypeScript
104+
105+ It is possible to have TypeScript transformer watch your PHP files for changes and automatically update the generated
106+ TypeScript files. You can do this by running:
107+
108+ ``` bash
109+ php artisan typescript:transform --watch
110+ ```
111+
112+ ## Laravel-specific features
113+
114+ This package provides some extra features on top of the base TypeScript transformer package tailed for Laravel
115+ applications. Let's go through them.
116+
117+ ### Your routes in TypeScript
118+
119+ Laravel provides a great way to define routes and then generate URLs to those routes in PHP using the ` route() ` helper.
120+ 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
121+ here by providing exact copy of the ` route() ` helper in TypeScript.
122+
123+ To add the helper, add the following provider to your ` TypeScriptTransformerServiceProvider ` :
124+
125+ ``` php
126+ use Spatie\LaravelTypeScriptTransformer\TransformedProviders\LaravelRouteTransformedProvider;
127+
128+ protected function configure(TypeScriptTransformerConfigFactory $config): void
129+ {
130+ $config->provider(new LaravelRouteTransformedProvider());
57131}
58132```
59133
60- This will be transformed to:
134+ The next time you run the ` typescript:transform ` command, a TypeScript function called ` route ` will be generated in
135+ the ` helpers/route.ts ` file.
136+
137+ You can now use the ` route ` function in your TypeScript code like this:
61138
62139``` ts
63- export type User = {
64- id: number ;
65- name: string ;
66- address: string | null ;
67- }
140+ import {route } from ' ./helpers/route' ;
141+
142+ // Without parameters
143+ const indexUrl = route (' users.index' );
144+ // https://laravel.dev/users
145+
146+ // With parameters
147+ const userUrl = route (' users.show' , {user: 1 });
148+ // https://laravel.dev/users/1
149+ ```
150+
151+ TypeScript will be smart enough to provide you autocompletion on these controllers and their parameters.
152+
153+ Sometimes you might want to exclude certain routes from being included in the generated TypeScript. You can do this by
154+ adding a route filter. The package provides three types of route filters:
155+
156+ ** NamedRouteFilter**
157+
158+ Allows you to remove routes by their name. It is possible to use wildcards.
159+
160+ ``` php
161+ use Spatie\LaravelTypeScriptTransformer\RouteFilters\NamedRouteFilter;
162+
163+ $config->provider(new LaravelRouteTransformedProvider(
164+ routeFilters: [
165+ new NamedRouteFilter('debugbar.*', 'hidden'),
166+ ],
167+ ));
168+ ```
169+
170+ ** ControllerRouteFilter**
171+
172+ Allows you to remove routes by their controller class or namespace using wildcards.
173+
174+ ``` php
175+ use Spatie\LaravelTypeScriptTransformer\RouteFilters\ControllerRouteFilter;
176+
177+ $config->provider(new LaravelRouteTransformedProvider(
178+ routeFilters: [
179+ new ControllerRouteFilter(['App\Http\Controllers\Admin\*', 'HiddenController']),
180+ ],
181+ ));
182+ ```
183+
184+ ** ClosureRouteFilter**
185+
186+ Allows you to provide a closure that will be called for each route. If the closure returns ` true ` , the route will be
187+ excluded.
188+
189+ ``` php
190+ use Spatie\LaravelTypeScriptTransformer\RouteFilters\ClosureRouteFilter;
191+
192+ $config->provider(new LaravelRouteTransformedProvider(
193+ routeFilters: [
194+ new ClosureRouteFilter(function (Route $route) {
195+ return str_starts_with($route->uri(), 'internal/');
196+ }),
197+ ],
198+ ));
199+ ```
200+
201+ By default, the helper will generate absolute URLs meaning it includes the app URL. This URL will be fetched from the
202+ window object in JavaScript. If you want to generate relative URLs instead, you can pass ` false ` as the third parameter,
203+ indicating you don't want absolute URLs:
204+
205+ ``` ts
206+ const indexUrl = route (' users.index' , {}, false );
207+ // /users
208+ ```
209+
210+ The default value of the absolute parameter can be changed by setting a default for the provider:
211+
212+ ``` php
213+ $config->provider(new LaravelRouteTransformedProvider(
214+ absoluteUrlsByDefault: false,
215+ ));
68216```
69217
70- Want to know more? You can find the documentation [here](https://docs.spatie.be/typescript-transformer/v2/introduction/).
218+ Now when using the ` route ` helper in TypeScript, URLs will be relative by default:
219+
220+ ``` ts
221+ const indexUrl = route (' users.index' );
222+ // /users
223+ ```
224+
225+ TypeScript transformer will automatically generate the ` helpers/route.ts ` file in the output directory you configured
226+ for TypeScript transformer. It is possible to change the path of this file as such:
227+
228+ ``` php
229+ $config->provider(new LaravelRouteTransformedProvider(
230+ path: 'route.ts',
231+ ));
232+ ```
233+
234+ When running in the watch mode of the package, the generated ` route.ts ` file will automatically be updated when you
235+ change your routes in Laravel. By default the watcher will monitor the following directories for changes:
236+
237+ - ` routes `
238+ - ` bootstrap `
239+ - ` app/Providers `
240+
241+ It is possible to customize the directories that are monitored as such:
242+
243+ ``` php
244+ $config->provider(new LaravelRouteTransformedProvider(
245+ routeDirectories: [
246+ 'custom/routes/directory',
247+ 'another/directory/to/watch',
248+ ],
249+ ));
71250
72251## Testing
73252
@@ -85,7 +264,8 @@ Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTI
85264
86265## Security
87266
88- If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.
267+ If you've found a bug regarding security please mail [ security@spatie.be ] ( mailto:security@spatie.be ) instead of using
268+ the issue tracker.
89269
90270## Credits
91271
0 commit comments