DEV Community

Vagebond
Vagebond

Posted on

From Inertia::render() to a page type

You type your Inertia props by hand. Then a controller changes, and the types drift.

Inertia Typegen generates TypeScript types and route helpers for Inertia pages. It reads them from Scramble's OpenAPI document. You write no types by hand.

This post walks from the PHP input to the TypeScript output.

Install

composer require vagebond/inertia-typegen
composer require --dev dedoc/scramble
Enter fullscreen mode Exit fullscreen mode

Scramble is a development dependency. Inertia Typegen requires PHP 8.3+, Laravel 12 or 13, and Scramble 0.13.49+. It also needs inertia-laravel 2 or 3, Node 22.18+ and Vite 6+.

The PHP input

Here is a controller with an enum and a paginated resource collection.

enum PostStatus: string
{
    case Draft = 'draft';
    case Published = 'published';
}

class PostController
{
    public function index()
    {
        return Inertia::render('Posts/Index', [
            'posts' => PostResource::collection(Post::paginate()),
            'status' => PostStatus::Draft,
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

The page type

Each Inertia::render() call becomes a page type. The output below is simplified for this post.

type PostStatus = 'draft' | 'published'

type PostsIndexProps = SharedData & {
  // the paginator keeps its real shape
  posts: PostCollection
  status: PostStatus
}
Enter fullscreen mode Exit fullscreen mode

Three things happen here.

  • PHP enums become a union of their values.
  • JSON resources, collections and paginators keep their real shape.
  • Shared data from the Inertia middleware becomes one type that each page type includes.

Form data

Form request rules become the type of the form data.

class StorePostRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'title' => ['required', 'string'],
            'status' => ['required', Rule::enum(PostStatus::class)],
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode
type StorePostData = {
  title: string
  status: PostStatus
}
Enter fullscreen mode Exit fullscreen mode

You change a rule in PHP. The form type follows.

Route helpers

You also get typed route helpers for each named route.

Keeping files fresh

The Vite dev server regenerates files after a PHP change. A CI check fails when committed files are stale. You commit the generated files, so a production build needs no PHP.

No HTTP endpoint is added by default. Plugins with hooks can change the document, routes and output.

The limit

The release status is 0.x. Minor releases can contain breaking changes until 1.0. So pin the minor version and check each upgrade.

Inertia Typegen is MIT licensed. The docs cover setup, route helpers and plugins:

https://baken.vagebond.nl/r/dpRMA9Ze

Top comments (0)