Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Typescript Transformer Laravel Package

spatie/laravel-typescript-transformer

Generate TypeScript types from your Laravel/PHP code. Convert classes, DTOs and enums (with attributes) into accurate TS definitions, supporting nullable fields, complex/generic types, and even TypeScript function generation via a simple CLI/workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-typescript-transformer --dev
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Spatie\LaravelTypeScriptTransformer\TypeScriptTransformerServiceProvider"
    
  2. First Use Case: Annotate a controller with #[TypeScript] and run the transformer:

    php artisan typescript:transform
    

    Output will be generated in resources/js/types/ (configurable). Example: resources/js/types/controllers/SomeController.d.ts

  3. Key Files:

    • config/typescript-transformer.php: Output paths, naming conventions, and new http_methods_priority (3.2.0+).
    • app/Http/Controllers/SomeController.php: Example controller to transform.
    • resources/js/types/controllers/SomeController.d.ts: Generated output with narrowed method types (e.g., 'get' | 'post' instead of string).

Implementation Patterns

Core Workflows

  1. Controller Transformation (3.2.0+):

    #[TypeScript]
    class SomeController extends Controller {
        public function index() { ... }
        public function store(Request $request) { ... }
        public function update(Request $request, $id) { ... }
    }
    

    Output (3.2.0):

    export type SomeController = {
        index: () => Promise<void>;
        store: (request: Request) => Promise<void>;
        update: (request: Request, id: string) => Promise<void>;
    };
    
    export type RouteDefinition = {
        path: string;
        method: 'get' | 'post' | 'put' | 'patch' | 'delete'; // Narrowed union (3.2.0)
        controller: SomeController;
    };
    
  2. HTTP Method Filtering (3.2.0): Configure http_methods_priority in typescript-transformer.php:

    'http_methods_priority' => ['get', 'post', 'put', 'patch', 'delete'],
    
    • Effect: Only routes matching these methods are emitted, in specified order.
    • Default: Excludes HEAD/OPTIONS (commonly unused in SPAs).
    • Customization: Add 'head' to include HEAD methods.
  3. Inertia.js Integration (3.2.0):

    router.visit(SomeController.update(), { data: { id: '1' } });
    

    Now works without type errors due to narrowed method types.

  4. Partial Transforms: Use #[TypeScript(only: ['index', 'store'])] to transform specific methods.

Advanced Patterns

  1. Dynamic Route Generation: Hook into typescript.transformed to extend route definitions:

    TypeScriptTransformer::macro('postProcess', function ($output) {
        return preg_replace('/method: string/', 'method: \'get\' | \'post\'', $output);
    });
    
  2. API Response Types: Transform DTOs for API contracts alongside controllers:

    #[TypeScript]
    class UserResponse {
        public User $data;
        public array<int, Meta> $meta;
    }
    
  3. Custom HTTP Methods: Override defaults to include HEAD:

    'http_methods_priority' => ['get', 'head', 'post'],
    

Gotchas and Tips

Common Pitfalls

  1. Breaking Change in 3.2.0:

    • Issue: method: stringmethod: 'get' | 'post' | 'put' | 'patch' | 'delete' (narrowed union).
      • Impact: Libraries expecting string (e.g., older Inertia versions) may fail.
    • Fix: Update dependencies or use postProcess macro to revert if needed.
  2. Missing HTTP Methods:

    • Issue: Routes using HEAD/OPTIONS are excluded by default.
    • Fix: Customize http_methods_priority in config to include 'head'.
  3. Circular References:

    • Issue: Controllers referencing each other may cause infinite loops.
    • Fix: Use #[TypeScript(ignore: true)] or manually resolve dependencies.
  4. Laravel-Specific Types:

    • Issue: Types like Request, Response, or Carbon may not map cleanly.
    • Fix: Register custom type mappings:
      TypeScriptTransformer::macro('laravelType', function ($type) {
          return match ($type) {
              'Illuminate\Http\Request' => 'Request',
              'Illuminate\Support\Carbon' => 'Date',
              default => $type,
          };
      });
      

Debugging Tips

  1. Dry Run: Preview output without writing files:

    php artisan typescript:transform --dry-run
    
  2. Verbose Logging: Enable debug mode in config:

    'debug' => true,
    
  3. Manual Overrides: Exclude problematic controllers:

    #[TypeScript(ignore: true)]
    class ComplexController { ... }
    

Extension Points

  1. Custom HTTP Methods: Extend http_methods_priority dynamically:

    config(['typescript-transformer.http_methods_priority' => ['get', 'post', 'head']]);
    
  2. Post-Processing: Modify generated types via typescript.transformed:

    event(new TypeScriptTransformed($className, $output));
    
  3. Webpack/Vite Integration: Ensure tsconfig.json includes:

    {
      "compilerOptions": {
        "typeRoots": ["./resources/js/types"]
      }
    }
    
  4. Inertia.js Compatibility: For libraries requiring string methods, use a macro:

    TypeScriptTransformer::macro('inertiaCompatible', function ($output) {
        return str_replace(
            "'get' | 'post' | 'put' | 'patch' | 'delete'",
            "string",
            $output
        );
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai