kiwilan/typescriptable-laravel

PHP package for Laravel to type Eloquent models and routes with autogenerated TypeScript, ready for Inertia with associated NPM package.


README

php laravel

version npm downloads license

tests codecov

PHP package for Laravel to type Eloquent models and routes with autogenerated TypeScript, ready for Inertia with associated NPM package.

PHP 8.1 is required and Laravel 9+ is recommended.

The package ziggy is NOT REQUIRED to use kiwilan/typescriptable-laravel.

Database Supported
MySQL
PostgreSQL
SQLite
SQL Server

Installation

You can install the package via composer:

composer require kiwilan/typescriptable-laravel

Configuration

You can publish the config file

php artisan vendor:publish --tag="typescriptable-config"

Update config file config/typescriptable.php

<?php

return [
    /**
     * The path to the output directory.
     */
    'output_path' => resource_path('js'),

    /**
     * Options for the models.
     */
    'models' => [
        'filename' => 'types-models.d.ts',
        /**
         * The path to the models directory.
         */
        'directory' => app_path('Models'),
        /**
         * Models to skip.
         */
        'skip' => [
            // 'App\\Models\\User',
        ],
        /**
         * Whether to add the LaravelPaginate type (with API type and view type).
         */
        'paginate' => true,
        /**
         * Whether to add the fake Jetstream Team type to avoid errors.
         */
        'fake_team' => false,
    ],
    /**
     * Options for the routes.
     */
    'routes' => [
        'filename' => 'types-routes.d.ts',
        'filename_list' => 'routes.ts',
        /**
         * Use routes `path` instead of `name` for the type name.
         */
        'use_path' => false,
        /**
         * Routes to skip.
         */
        'skip' => [
            'name' => [
                'debugbar.*',
                'horizon.*',
                'telescope.*',
                'nova.*',
                'lighthouse.*',
                'livewire.*',
                'ignition.*',
                'filament.*',
            ],
            'path' => [
                'api/*',
            ],
        ],
    ],
];

Usage

php artisan typescriptable
  • --A|all: Generate all types.
  • --M|models: Generate Models types.
  • --R|routes: Generate Routes types.

Eloquent Models

Generate resources/js/types-models.d.ts file with all models types.

php artisan typescriptable:models
  • Generate TS types for Eloquent models
  • Generate TS types for Eloquent relations (except morphTo)
  • Generate TS types for casts (include native enum support)
  • Generate TS types for dates
  • Generate TS types for appends (partial for Casts\Attribute, you can use old way to define get*Attribute methods)
  • Generate TS types counts
  • Generate pagination TS types for Laravel pagination with option paginate

Routes

Generate resources/js/types-routes.d.ts file with all routes types and resources/js/routes.ts for routes references.

php artisan typescriptable:routes

Inertia

You can use associated NPM package @kiwilan/typescriptable-laravel to use helpers with typescriptable:models and typescriptable:routes commands.

  • Execute automatically typescriptable:models and typescriptable:routes commands with watch mode.
  • A composable useInertiaTyped with typed router, typed usePage and some helpers.
  • A Vue component Route with typed to prop.
  • A Vue plugin to inject all new features.
  • All Inertia types for page and global properties.

Examples

Eloquent Models

An example of Eloquent model.

<?php

namespace App\Models;

use Kiwilan\Steward\Enums\PublishStatusEnum;

class Story extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'abstract',
        'original_link',
        'picture',
        'status',
        'published_at',
        'meta_title',
        'meta_description',
    ];

    protected $appends = [
        'time_to_read',
    ];

    protected $withCount = [
        'chapters',
    ];

    protected $casts = [
        'status' => PublishStatusEnum::class,
        'published_at' => 'datetime:Y-m-d',
    ];

    public function getTimeToReadAttribute(): int

    public function chapters(): HasMany

    public function category(): BelongsTo

    public function author(): BelongsTo

    public function tags(): BelongsToMany
}

TS file generated at resources/js/types-models.d.ts

declare namespace App {
    declare namespace Models {
        export type Story = {
            id: number;
            title: string;
            slug?: string;
            abstract?: string;
            original_link?: string;
            picture?: string;
            status: "draft" | "scheduled" | "published";
            published_at?: Date;
            meta_title?: string;
            meta_description?: string;
            created_at?: Date;
            updated_at?: Date;
            author_id?: number;
            category_id?: number;
            time_to_read?: number;
            chapters?: Chapter[];
            category?: Category;
            author?: Author;
            tags?: Tag[];
            chapters_count?: number;
            tags_count?: number;
        };
    }
    // With `paginate` option.
    export type PaginateLink = {
        url: string;
        label: string;
        active: boolean;
    };
    export type Paginate<T = any> = {
        data: T[];
        current_page: number;
        first_page_url: string;
        from: number;
        last_page: number;
        last_page_url: string;
        links: App.PaginateLink[];
        next_page_url: string;
        path: string;
        per_page: number;
        prev_page_url: string;
        to: number;
        total: number;
    };
}

Usage in Vue component.

<script lang="ts" setup>
defineProps<{
    story?: App.Models.Story;
}>();
</script>

Or with paginate option.

<script lang="ts" setup>
defineProps<{
    stories?: App.Paginate<App.Models.Story>;
}>();
</script>

Testing

cp .env.example .env
composer test

Roadmap

  • 90% coverage
  • Generate TS types for morphTo
  • Use appends to define type for Casts\Attribute methods

Changelog

Please see CHANGELOG for more information on what has changed recently.

Credits

License

The MIT License (MIT). Please see License File for more information.