oi-lab / oi-laravel-ts
Generate TypeScript interfaces from Laravel Eloquent models
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/oi-lab/oi-laravel-ts
Requires
- php: ^8.2|^8.3|^8.4
- illuminate/console: ^11.0|^12.0
- illuminate/database: ^11.0|^12.0
- illuminate/filesystem: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^9.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
README
A Laravel package that automatically generates TypeScript interfaces from your Eloquent models, complete with relationships, custom casts, and DataObjects support.
Features
- Automatic Interface Generation: Converts Eloquent models to TypeScript interfaces
- Relationship Support: Handles all Laravel relationship types (HasOne, HasMany, BelongsTo, etc.)
- Custom Casts: Supports Laravel custom casts and automatically detects DataObjects
- PHPDoc Support: Reads PHPDoc annotations for complex types
- Watch Mode: Monitor your models directory and regenerate on changes
- Configurable: Extensive configuration options for customization
- JSON-LD Support: Optional support for JSON-LD data structures
Architecture
This package uses a modular architecture with clear separation of concerns, organized in two main pipelines:
Pipeline 1: Eloquent Analysis
- Eloquent: Facade for model analysis and schema generation
- ModelDiscovery: Discovers all Eloquent models in the application
- TypeExtractor: Extracts type information from models
- CastTypeResolver: Resolves custom Laravel casts to TypeScript types
- RelationshipResolver: Detects and extracts relationship metadata
- DataObjectAnalyzer: Analyzes PHP DataObject classes
- PhpToTypeScriptConverter: Converts PHP types to TypeScript
- SchemaBuilder: Orchestrates schema building for all models
Pipeline 2: TypeScript Generation
- Convert: Main orchestrator coordinating the conversion process
- TypeScriptTypeConverter: Handles schema to TypeScript type conversion
- DataObjectProcessor: Processes PHP DataObjects and generates their interfaces
- ModelInterfaceGenerator: Generates TypeScript interfaces for Laravel models
- ImportManager: Manages TypeScript import statements
- JsonLdGenerator: Generates JSON-LD support interfaces
For detailed architecture documentation, see ARCHITECTURE.md.
Requirements
- PHP 8.2+
- Laravel 11.0+ or 12.0+
Installation
Via Composer
If the package is published on Packagist:
composer require oi-lab/oi-laravel-ts
Via GitHub (Private Repository)
Add the repository to your composer.json:
{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/oi-lab/oi-laravel-ts"
        }
    ]
}
Then require the package:
composer require oi-lab/oi-laravel-ts
Local Development
For local development, add this to your main project's composer.json:
{
    "repositories": [
        {
            "type": "path",
            "url": "./packages/oi-lab/oi-laravel-ts"
        }
    ]
}
Then:
composer require oi-lab/oi-laravel-ts
Configuration
Publish the configuration file:
php artisan vendor:publish --tag=oi-laravel-ts-config
This creates config/oi-laravel-ts.php with the following options:
return [ // Output path for generated TypeScript file 'output_path' => resource_path('js/types/interfaces.ts'), // Include _count fields for relationships 'with_counts' => true, // Enable JSON-LD support 'with_json_ld' => false, // Save intermediate schema.json for debugging 'save_schema' => false, // Define specific types for model properties 'props_with_types' => [], // Add custom properties to models 'custom_props' => [ 'Organization' => [ 'uuid' => 'string', ], ], ];
Usage
Basic Generation
Generate TypeScript interfaces from your models:
php artisan oi:gen-ts
This will scan all models in app/Models and generate a TypeScript file at the configured output path.
Watch Mode
Automatically regenerate when models change:
php artisan oi:gen-ts --watch
Example Output
Given a Laravel model:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model { protected $fillable = ['name', 'email', 'bio']; protected $casts = [ 'email_verified_at' => 'datetime', ]; public function posts(): HasMany { return $this->hasMany(Post::class); } }
The package generates:
export interface IUser { id: number; name: string; email: string; bio: string; email_verified_at?: string; created_at: string; updated_at: string; posts?: IPost[]; posts_count?: number; }
Advanced Features
Custom Properties
Add properties that aren't in your database schema:
// config/oi-laravel-ts.php 'custom_props' => [ 'User' => [ 'full_name' => 'string', 'avatar_url' => 'string', ], ],
DataObject Support
The package automatically detects and converts custom DataObjects:
// Your model class Page extends Model { protected $casts = [ 'metadata' => MetadataCast::class, ]; } // Your Cast class MetadataCast implements CastsAttributes { public function get($model, string $key, $value, array $attributes): Metadata { return Metadata::fromArray(json_decode($value, true)); } } // Generated TypeScript export interface IMetadata { title: string; description?: string; } export interface IPage { id: number; metadata?: IMetadata | null; }
Import External Types
Reference external TypeScript types:
'custom_props' => [ 'User' => [ 'settings' => '@/types/settings|UserSettings', ], ],
Generates:
import { UserSettings } from '@/types/settings'; export interface IUser { settings: UserSettings; }
Examples
Complete Workflow
- Define your models with relationships and casts
- Configure custom properties if needed
- Run the generator:
php artisan oi:gen-ts
- Use the generated interfaces in your TypeScript code:
import { IUser, IPost } from '@/types/interfaces'; const user: IUser = await fetchUser(); const posts: IPost[] = user.posts || [];
Integration with Inertia.js
import { PageProps } from '@inertiajs/core'; import { IUser } from '@/types/interfaces'; interface Props extends PageProps { user: IUser; } export default function Dashboard({ user }: Props) { // TypeScript knows all User properties console.log(user.email); }
Testing
This package includes comprehensive test coverage with 39 tests and 160 assertions.
Run Tests
# Run all tests vendor/bin/pest # Run specific test suite vendor/bin/pest tests/Unit vendor/bin/pest tests/Feature # Run with coverage vendor/bin/pest --coverage
Test Coverage
- ✅ Type conversion (PHP → TypeScript)
- ✅ Model analysis and schema building
- ✅ Relationship detection (HasMany, BelongsTo, etc.)
- ✅ Custom cast resolution
- ✅ DataObject handling
- ✅ TypeScript interface generation
- ✅ Integration tests for full pipeline
For detailed testing documentation, see TESTING.md.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
When contributing:
- Write tests for new features
- Ensure all tests pass: vendor/bin/pest
- Follow existing code style
- Update documentation as needed
License
This package is open-source software licensed under the MIT license.
Credits
Olivier Lacombe - Creator and maintainer
Olivier is a Product & Technology Director based in Montpellier, France, with over 20 years of experience innovating in UX/UI and emerging technologies. He specializes in guiding enterprises toward cutting-edge digital solutions, combining user-centered design with continuous optimization and artificial intelligence integration.
Projects & Resources:
- OnAI - Training courses and masterclasses on generative AI for businesses
- Promptr - Prompt engineering Management Platform
Support
For support, please open an issue on the GitHub repository.