Back to blog

Leveraging Laravel, Inertia, Vue.js, and TypeScript for Full-Stack Type Safety

·2 min read
LaravelVueTypeScriptInertia

Type safety is one of those things that, once you have it, you wonder how you ever lived without it. In this post, I'll walk through how I set up full-stack type safety with Laravel, Inertia.js, Vue.js, and TypeScript.

The Goal

We want TypeScript to know exactly what data our Laravel backend is sending to our Vue frontend. No more any types, no more guessing at property names.

Setting Up Laravel Data

First, install Spatie's Laravel Data package:

composer require spatie/laravel-data

Create a Data Transfer Object:

class UserData extends Data
{
    public function __construct(
        public int $id,
        public string $name,
        public string $email,
        public ?string $avatar,
    ) {}
}

Generating TypeScript Types

Use Laravel TypeScript Transformer to generate TypeScript interfaces:

composer require spatie/laravel-typescript-transformer
php artisan typescript:generate

This generates:

interface UserData {
  id: number;
  name: string;
  email: string;
  avatar: string | null;
}

Using in Vue Components

Now in your Vue component:

<script setup lang="ts">
import type { UserData } from '@/types';
 
defineProps<{
  user: UserData;
}>();
</script>

Full autocompletion, type checking, and refactoring support. Your IDE now knows exactly what user.name is.


This setup has saved me countless hours of debugging and made refactoring significantly less scary. The upfront investment pays dividends.