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 Model Typescript Transfomer Laravel Package

nolanos/laravel-model-typescript-transfomer

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:
    composer require nolanos/laravel-model-typescript-transformer
    
  2. Configure: Append Nolanos\LaravelModelTypescriptTransformer\ModelTypeScriptCollector to collectors and Nolanos\LaravelModelTypescriptTransformer\ModelTransformer to transformers in config/typescript-transformer.php.
  3. Generate Types: Run:
    php artisan typescript:generate
    
    Outputs TypeScript definitions to resources/js/types/models.d.ts (default).

First Use Case

Generate TypeScript interfaces for a User model with a posts() relationship:

// app/Models/User.php
class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

After running typescript:generate, you’ll get:

interface User {
    id: number;
    name: string;
    email: string;
    // ...other columns
    posts: Post[];
}

Implementation Patterns

Workflows

  1. Incremental Generation: Use --only flag to regenerate specific models:
    php artisan typescript:generate --only=User,Post
    
  2. Customizing Output: Override default output path in config/typescript-transformer.php:
    'output_path' => 'resources/js/types/custom-models.d.ts',
    
  3. Excluding Models: Add ModelTransformer::class to ignored_transformers in config to skip specific models.

Integration Tips

  • Laravel Scout: If using Scout, extend ModelTransformer to include searchableAs:
    // app/Providers/AppServiceProvider.php
    $transformer->extend('User', function ($model) {
        return collect($model->getFillable())
            ->merge(['searchableAs' => $model->searchableAs]);
    });
    
  • Polymorphic Relations: Add custom logic to handle polymorphic types:
    // config/typescript-transformer.php
    'transformers' => [
        \Nolanos\LaravelModelTypescriptTransformer\ModelTransformer::class,
        \App\Transformers\PolymorphicTransformer::class,
    ],
    
  • API Resources: Sync TypeScript types with API resources by extending ModelTransformer to include toArray() fields.

Example: Custom Transformer

// app/Transformers/CustomModelTransformer.php
namespace App\Transformers;

use Nolanos\LaravelModelTypescriptTransformer\ModelTransformer;

class CustomModelTransformer extends ModelTransformer
{
    protected function getTypeForColumn($column, $model)
    {
        if ($column === 'status') {
            return 'UserStatus'; // Custom enum/type
        }
        return parent::getTypeForColumn($column, $model);
    }
}

Gotchas and Tips

Pitfalls

  1. Hidden/Visible Attributes: The transformer respects $hidden and $visible properties, but casts are ignored. Manually override types for casted attributes (e.g., datestring):

    // Override in config or custom transformer
    $transformer->extend('User', function ($model) {
        return collect($model->getFillable())
            ->mapWithKeys(fn ($value, $key) => [
                'created_at' => 'string', // Force string for date
                'password' => 'string',
            ]);
    });
    
  2. Relationships:

    • Many-to-Many: Defaults to Model[]. Customize via ModelTransformer::extend():
      $transformer->extend('User', function ($model) {
          return collect($model->getRelations())
              ->mapWithKeys(fn ($relation) => [
                  'roles' => 'Role[]', // Override default
              ]);
      });
      
    • Polymorphic: Not auto-detected. Use a custom transformer or extend ModelTransformer to handle morphTo/morphWith.
  3. Database Schema Changes: Regenerate types after schema changes:

    php artisan typescript:generate --force
    

    The --force flag overwrites existing files.

  4. Circular Dependencies: If models reference each other (e.g., User has posts, Post has user), TypeScript may complain. Use interfaces or type aliases in your .d.ts:

    // resources/js/types/models.d.ts
    interface User {
        posts: Post[];
    }
    interface Post {
        user: User;
    }
    

Debugging

  • Log Generation: Enable verbose output to debug type mappings:
    php artisan typescript:generate --verbose
    
  • Inspect Collectors: Check ModelTypeScriptCollector to verify which models are being processed. Override getModels() if needed:
    // app/Providers/AppServiceProvider.php
    $collector->extend('models', function () {
        return [User::class, Post::class]; // Custom list
    });
    

Extension Points

  1. Custom Type Mappings: Override getTypeForColumn() in a custom transformer for non-standard DB types (e.g., jsonRecord<string, unknown>).
  2. Pre/Post Processing: Use ModelTransformer::extend() to modify types before/after generation:
    $transformer->extend('User', function ($model) {
        return collect($model->getFillable())
            ->merge(['avatar' => 'string | null']); // Custom union type
    });
    
  3. Hooks: Bind to typescript.generated event to post-process files:
    // app/Providers/AppServiceProvider.php
    event(new \Spatie\LaravelTypeScriptTransformer\Events\TypeScriptGenerated(
        $path,
        $content
    ));
    

Config Quirks

  • Default Paths: Ensure output_path in config/typescript-transformer.php is writable. Default: resources/js/types/models.d.ts.
  • Namespace Handling: The transformer uses the model’s class name as the TypeScript interface name. For namespaced models (e.g., App\Models\User), the output will be AppModelsUser. Override via getInterfaceName() in a custom transformer:
    protected function getInterfaceName($model)
    {
        return 'User'; // Flatten namespace
    }
    
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