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 Resources Typescript Laravel Package

diephp/laravel-resources-typescript

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require diephp/laravel-resources-typescript
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Diephp\LaravelResourcesTypescript\LaravelResourcesTypescriptServiceProvider" --tag="config"
    
  2. Generate Types Run the Artisan command to generate TypeScript interfaces in resources/ts (default):

    php artisan resources:typescript
    

    Or specify a custom output path:

    php artisan resources:typescript --output=path/to/types
    
  3. First Use Case Define a Laravel JsonResource (e.g., app/Http/Resources/UserResource.php):

    namespace App\Http\Resources;
    
    use Illuminate\Http\Resources\Json\JsonResource;
    
    class UserResource extends JsonResource
    {
        public function toArray($request): array
        {
            return [
                'id' => $this->id,
                'name' => $this->name,
                'email' => $this->email,
                'role' => $this->role,
            ];
        }
    }
    

    Run the command, and the package generates a TypeScript interface like:

    export interface UserResource {
        id: number;
        name: string;
        email: string;
        role: string;
    }
    

Implementation Patterns

Core Workflow

  1. Resource Definition Use standard Laravel JsonResource classes with:

    • toArray() methods.
    • Typed properties (e.g., public int $id).
    • PHPDoc or #[ArrayShape] annotations.
  2. Type Generation

    • Automatic Detection: Run php artisan resources:typescript in your dev environment.
    • Incremental Updates: Regenerate only changed resources with --force or --watch (if supported in future versions).
  3. Integration with Frontend

    • Import generated types in your frontend (e.g., Vue/React/Angular) projects:
      import { UserResource } from './path/to/generated/types';
      
    • Use in API clients or state management:
      interface ApiResponse {
        data: UserResource[];
      }
      
  4. Enum Support Define enums in PHP (e.g., app/Enums/UserRole.php):

    namespace App\Enums;
    
    enum UserRole: string {
        case ADMIN = 'admin';
        case USER = 'user';
    }
    

    Reference them in resources:

    public function toArray($request): array {
        return ['role' => $this->role->value];
    }
    

    The package generates:

    export type UserRole = 'admin' | 'user';
    export interface UserResource {
        role: UserRole;
    }
    
  5. Customizing Output Override default behavior via resources-typescript.php config:

    return [
        'output_path' => 'path/to/custom/types',
        'namespace' => 'CustomNamespace',
        'exclude' => [
            'App\Http\Resources\ExcludedResource',
        ],
    ];
    

Gotchas and Tips

Pitfalls

  1. Unsafe Type Inference

    • The package falls back to any for ambiguous types (e.g., dynamic toArray() logic). Explicitly type properties or use PHPDoc to avoid this:
      /**
       * @return array{id: int, name: string}
       */
      public function toArray($request): array { ... }
      
  2. Circular Dependencies

    • If resources reference each other (e.g., UserResource includes PostResource), the generated types may fail. Use @mixin in TypeScript or refactor to avoid circularity.
  3. Enum Limitations

    • Only PHP 8.1+ enums are supported. Backport enums or use string constants for older PHP versions.
  4. Cache Invalidation

    • Regenerate types after changes to resources or enums. Use --force to overwrite cached files:
      php artisan resources:typescript --force
      

Debugging

  • Verbose Output: Enable debug mode in config:

    'debug' => true,
    

    Run the command to see analyzed resources and generated types.

  • Manual Overrides: Override generated types in your frontend project to handle edge cases:

    // Override a specific interface
    interface UserResource {
        customField?: string; // Not detected by the package
    }
    

Extension Points

  1. Custom Type Mappings Extend the package by implementing a TypeMapper to handle custom PHP types (e.g., Carbon instances):

    namespace App\Services;
    
    use Diephp\LaravelResourcesTypescript\Contracts\TypeMapper;
    
    class CarbonTypeMapper implements TypeMapper
    {
        public function getType(string $value): string
        {
            return 'string'; // Map Carbon to ISO string
        }
    }
    

    Register in AppServiceProvider:

    public function boot(): void
    {
        $this->app->bind(TypeMapper::class, CarbonTypeMapper::class);
    }
    
  2. Post-Processing Use a build tool (e.g., Vite, Webpack) to transform generated types. Example: Add readonly modifiers or rename fields:

    // vite.config.ts
    import { defineConfig } from 'vite';
    import ts from '@rollup/plugin-typescript';
    
    export default defineConfig({
        plugins: [
            ts({
                transform: (code) => {
                    return code.replace(
                        /interface (\w+)/g,
                        'interface $1 { readonly '
                    );
                },
            }),
        ],
    });
    
  3. Testing Test type generation by mocking resources and asserting output:

    use Diephp\LaravelResourcesTypescript\TypeGenerator;
    
    public function test_type_generation()
    {
        $generator = new TypeGenerator();
        $resource = new UserResource(new User());
        $type = $generator->generate($resource);
    
        $this->assertStringContainsString('interface UserResource', $type);
    }
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
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