Typed Page Props¶
Type-safe props for your Inertia page components.
Overview¶
Litestar-Vite generates TypeScript types for your page props:
@get("/dashboard", component="Dashboard")
async def dashboard() -> dict:
return {
"userCount": 42,
"recentActivity": [...],
}
Generates:
interface PageProps {
Dashboard: {
userCount: number;
recentActivity: any[];
};
}
Using PageProps¶
Import and use the generated types:
import type { PageProps } from "@/generated/page-props";
export default function Dashboard(props: PageProps["Dashboard"]) {
return (
<div>
<h1>Dashboard</h1>
<p>Users: {props.userCount}</p>
{props.recentActivity.map((item) => (
<ActivityItem key={item.id} item={item} />
))}
</div>
);
}
<script setup lang="ts">
import type { PageProps } from "@/generated/page-props";
const props = defineProps<PageProps["Dashboard"]>();
</script>
<template>
<div>
<h1>Dashboard</h1>
<p>Users: {{ props.userCount }}</p>
</div>
</template>
<script lang="ts">
import type { PageProps } from "@/generated/page-props";
let { userCount, recentActivity }: PageProps["Dashboard"] = $props();
</script>
<div>
<h1>Dashboard</h1>
<p>Users: {userCount}</p>
</div>
Type Inference¶
Types are inferred from your Python return types:
from dataclasses import dataclass
@dataclass
class DashboardStats:
user_count: int
active_sessions: int
revenue: float
@get("/dashboard", component="Dashboard")
async def dashboard() -> dict:
stats = DashboardStats(user_count=42, active_sessions=10, revenue=1234.56)
return {"stats": stats}
Generates types based on serialization output.
Nested Components¶
Use path separators for component organization:
@get("/users", component="Users/Index")
async def list_users() -> dict: ...
@get("/users/{id}", component="Users/Show")
async def show_user(id: int) -> dict: ...
Access via:
PageProps["Users/Index"]
PageProps["Users/Show"]
With usePage Hook¶
Using the Inertia usePage hook:
import { usePage } from "@inertiajs/react";
import type { PageProps, FullSharedProps } from "@/generated/page-props";
type AllProps = PageProps["Dashboard"] & FullSharedProps;
export default function Dashboard() {
const { props } = usePage<{ props: AllProps }>();
return <p>Users: {props.userCount}</p>;
}
Regenerating Types¶
Types are regenerated when you run:
litestar assets generate-types
Or automatically during build:
litestar assets build
Handling Optional Props¶
Optional props are marked with ?:
@get("/users/{id}", component="Users/Show")
async def show_user(id: int) -> dict:
user = await User.get_or_none(id)
return {
"user": user, # Can be None
"posts": user.posts if user else [],
}
PageProps["Users/Show"] = {
user: User | null;
posts: Post[];
}
See Also¶
TypeScript Integration - TypeScript overview
Shared Props Typing - Extending SharedProps
Type Generation - Generation configuration