Skip to content

Conversation

@pascalbaljet
Copy link
Member

@pascalbaljet pascalbaljet commented Oct 16, 2025

This PR allows you to type-hint shared page props in a global type definition file, for example, resources/js/types/globals.d.ts.

declare module '@inertiajs/core' {
  export interface InertiaConfig {
    sharedPageProps: {
      auth: { user: { id: number; name: string } | null }
      flash: { success?: string; error?: string }
    }
  }
}

Now the shared page props are automatically type-hinted throughout the app when you use usePage().

const page = usePage()
const successMessage = page.props.flash.success 

In the example above, successMessage will be typed as string | undefined. In Svelte and Vue, this also works in the template.

<template>
  <p>{{ $page.props.flash.error }}</p>

  <!-- @vue-expect-error - 'message' does not exist on flash -->
  {{ $page.props.flash.message }}
</template>

You can still pass an interface to usePage() for page-specific props, which will automatically be merged with the declared sharedPageProps.

type PageProps = {
  posts: { id: number; title: string }[]
}

const page = usePage<PageProps>()
const successMessage = page.props.flash.success
const postTitles = page.props.posts.map((post) => post.title)

In this case, postTitles will be typed as string[].

For reference, previously, you could already partially do this by extending the PageProps interface.

type SharedPageProps = {
  flash: { error?: string; success?: string }
}

declare module '@inertiajs/core' {
  interface PageProps extends PageProps, SharedPageProps {}
}

The problem with this approach is that the shared page props are overwritten when you pass a specific interface to usePage().

type PageProps = {
  posts: { id: number; title: string }[]
}

const page = usePage<PageProps>()
const successMessage = page.props.flash.success // <== No longer typed! (shared props are lost)
const postTitles = page.props.posts.map((post) => post.title)

This was originally planned in PR #2549, but I decided to split it up into multiple PRs for clarity.

@pascalbaljet pascalbaljet changed the title Support for typehinting shared Page rops Support for type-hinting shared Page Props Oct 16, 2025
@pascalbaljet
Copy link
Member Author

I also brings usePage() to the Svelte adapter!

<script lang="ts">
  import { usePage } from '@inertiajs/svelte'

  type PageProps = {
    posts: { id: number; title: string }[]
  }

  const page = usePage<PageProps>()

  $: error = $page.props.flash.error
  $: postTitles = $page.props.posts.map((post) => post.title)
</script>

@pascalbaljet pascalbaljet added the typescript Related to TypeScript implementation label Oct 16, 2025
@pascalbaljet pascalbaljet merged commit 5fe7eb1 into master Oct 16, 2025
12 checks passed
@pascalbaljet pascalbaljet deleted the typed-shared-props branch October 16, 2025 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

typescript Related to TypeScript implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants