Loading...
Loading...
TypeScript type safety for Inertia Rails (React, Vue, Svelte): shared props, flash, and errors via InertiaConfig module augmentation in globals.d.ts. Use when setting up TypeScript types, configuring shared props typing, fixing TS2344 or TS2339 errors in Inertia components, or adding new shared data.
npx skill4agent add inertia-rails/skills inertia-rails-typescriptglobals.d.tsInertiaConfigSharedPropsFlashDataindex.tsglobals.d.tsusePage()type Props = { ... }sharedPagePropsflashDataTypeerrorValueType// app/frontend/types/globals.d.ts
import type { FlashData, SharedProps } from '@/types'
declare module '@inertiajs/core' {
export interface InertiaConfig {
sharedPageProps: SharedProps // EXACT name — auto-typed for usePage().props
flashDataType: FlashData // EXACT name — auto-typed for usePage().flash
errorValueType: string[] // EXACT name — errors are arrays of strings
}
}// app/frontend/types/index.ts
export interface FlashData {
notice?: string
alert?: string
}
export interface SharedProps {
auth: { user?: { id: number; name: string; email: string } }
}auth: { user: ... }inertia_share{ auth: { user: current_user } }authusercurrent_user:user:// BAD — passing shared props as generics:
// usePage<{ users: User[], auth: AuthData, flash: FlashData }>()
// BAD — extending a SharedProps interface into page props:
// interface Props extends SharedData { users: User[] }
// BAD — declaring PageProps interface:
// interface PageProps { auth: AuthData; flash: FlashData }
// BAD — using current_user or user as top-level shared key:
// interface SharedProps { current_user: User }
// BAD — destructuring auth directly from usePage() (TS2339: 'auth' does not exist on Page):
// const { auth } = usePage()
// usePage() returns a Page object with { props, flash, component, url, ... }
// auth lives inside props, not on the Page itself
// BAD — duplicating InertiaConfig in index.ts (it belongs in globals.d.ts):
// declare module '@inertiajs/core' { ... } ← in index.ts
// GOOD — props from usePage().props, flash from usePage().flash:
const { props, flash } = usePage()
// props.auth is typed (from SharedProps via InertiaConfig)
// flash.notice is typed (from FlashData via InertiaConfig)globals.d.tsindex.tsglobals.d.ts// BEFORE — app/frontend/types/index.ts
export interface SharedProps {
auth: { user?: { id: number; name: string; email: string } }
}
// AFTER — add the new key here, NOT in globals.d.ts
export interface SharedProps {
auth: { user?: { id: number; name: string; email: string } }
notifications: { unread_count: number }
}globals.d.tsSharedPropsdeclare module '@inertiajs/core'typeinterfacedefineProps<T>()$props()usePage<T>()interfaceusePage<T>()TtypeinterfaceinterfaceusePage| Pattern | Works with | Notes |
|---|---|---|
| Yes | Preferred — just works |
| No — TS2344 | Missing index signature |
| Yes | Wraps interface to add index signature |
// React
type Props = {
users: User[] // page-specific only
// auth is NOT here — it comes from InertiaConfig globally
}
export default function Index({ users }: Props) {
// Access shared props separately:
const { props, flash } = usePage()
// props.auth is typed via InertiaConfig
// flash.notice is typed via InertiaConfig
return <UserList users={users} />
}<!-- Vue 3 — usePage() returns reactive object; use computed() for derived values -->
<script setup lang="ts">
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
const page = usePage()
const userName = computed(() => page.props.auth.user?.name) // typed via InertiaConfig
</script><!-- Svelte — page store from @inertiajs/svelte -->
<script lang="ts">
import { page } from '@inertiajs/svelte'
// $page.props.auth is typed via InertiaConfig
// $page.flash.notice is typed via InertiaConfig
</script>| Error | Cause | Fix |
|---|---|---|
TS2344 on | | Use |
TS2339 | Destructuring | |
TS2339 | Accessing | Flash is top-level: |
| Shared props untyped | Missing InertiaConfig | Add |
| InertiaConfig not taking effect | Declaration in wrong file | Must be in a |
| Types correct but IDE shows errors | | Verify |
typelizeralba-inertiaSharedPropsindex.tsglobals.d.tsSharedPropsResourceindex.tsinertia-rails-controllersinertia-rails-controllersalba-inertiainertia-rails-pages