-
-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(types): add InertiaPage type helper #110
base: main
Are you sure you want to change the base?
Conversation
3b1315c
to
bbc2bf3
Compare
bbc2bf3
to
d9088f4
Compare
Great work. Can you please update the readme? |
Added a readme. Is the name of the Type good in your opinion? With this approach there is the need to make a new type and export it for every controller method. If this is a resource method, It could end up being annoying to do so. I think I can take it one step further and allow for something like type FooControllerProps = InertiaController<FooController> which would produce something like type FooControllerProps = {
index: {
foos: string[]
}
show: {
foo: string
}
} |
🤔 I think I like the second approach better since it's less verbose. |
On the client you would use it like so import type FooControllerProps from 'App/Controllers/FooController'
const FooPage = ({ bar }: FooControllerProps['show']) => {
return <div>{bar}</div>
} The type to get this to work is type InertiaController<T> = {
[K in keyof T]: T[K] extends AdonisControllerMethod
? InertiaPage<T[K]>
: never
} This works, but after a little more testing, As an example of what I am talking about. If we have the folllowing export default class FooController {
public async index({ inertia, request }: HttpContextContract) {
if(request.params().noInertia) {
return {
test: 'test',
}
}
return inertia.render('Foo', {
bar: "FooBar",
})
}
}
InertiaPage<FooController['index']> // = unknown |
thanks. it's an interesting problem. |
I think there is ways around it. I'll have more time to dig in over the next few days and see what kind of solution I can come up with. |
Hello, I'm a bit late, but I usually use this for type safety: // app/utils/inertiaRender.ts
import { ComponentProps } from 'react'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export const inertiaRender = async <T extends (props: any) => JSX.Element>(
inertia: HttpContextContract['inertia'],
component: T,
props: ComponentProps<T>
) => {
return inertia.render(component.name, props)
} // resources/js/Pages/Home.tsx
const Home = ({ email }: { email: string }) => <h1>Hello {email}</h1> // app/Controllers/Http/home/HomeController.ts
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Home from 'Resources/js/Pages/Home'
import { inertiaRender } from 'App/utils/inertiaRender'
export default class HomeController {
public async index({ inertia, auth }: HttpContextContract) {
const user = auth.user!
return inertiaRender(inertia, Home, { email: user.email })
}
} |
Based off of my enhancement request here #109
The Problem
When using Inertia with Typescript there is currently no type safety when it comes to the frontend framework page that is rendered.
You can do something like this but we are sort of just faking the type safety here because things can get out of sync
Simply by adding some generics to the Inertia.render function we can then create a helper type that can pull the ResponseProps out for us.
So now we can do the following
FooIndexProps now equals