From d9088f49712fb1d6048e0a77b8e6b95d85c90e95 Mon Sep 17 00:00:00 2001 From: Cody Tooker Date: Sun, 5 Mar 2023 23:00:18 -0600 Subject: [PATCH 1/2] feat(types): add InertiaPage type helper --- adonis-typings/inertia.ts | 14 +++++++++++--- src/Inertia.ts | 10 +++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/adonis-typings/inertia.ts b/adonis-typings/inertia.ts index 313a5b7..30e24b5 100644 --- a/adonis-typings/inertia.ts +++ b/adonis-typings/inertia.ts @@ -2,8 +2,16 @@ declare module '@ioc:EidelLev/Inertia' { import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import { ResponseContract } from '@ioc:Adonis/Core/Response'; - export type ResponseProps = Record; - export type RenderResponse = Promise | string | ResponseContract>; + type AdonisControllerMethod = (ctx: HttpContextContract, ...args: any) => any; + export type ResponseProps = Record; + type RenderedResponseProps = { + component: string; + version: VersionValue; + props: T; + url: string; + } + export type RenderResponse = Promise | string | ResponseContract>; + export type InertiaPage = Exclude>, string | ResponseContract>['props']; /** * Shared data types @@ -31,7 +39,7 @@ declare module '@ioc:EidelLev/Inertia' { * @param {string} component Page component * @param {ResponseProps} responseProps Props */ - render(component: string, responseProps?: ResponseProps, pageOnlyProps?: ResponseProps): RenderResponse; + render(component: string, responseProps?: T, pageOnlyProps?: ResponseProps): RenderResponse; /** * Redirect back with the correct HTTP status code diff --git a/src/Inertia.ts b/src/Inertia.ts index 3c23d4e..0400113 100644 --- a/src/Inertia.ts +++ b/src/Inertia.ts @@ -49,19 +49,19 @@ export class Inertia implements InertiaContract { return new LazyProp(callback); } - public async render( + public async render( component: string, - responseProps: ResponseProps = {}, + responseProps?: T, pageOnlyProps: ResponseProps = {}, - ): RenderResponse { + ): RenderResponse { const { view: inertiaView, ssr = { enabled: false } } = this.config; const { request, response, view, session } = this.ctx; const isInertia = request.inertia(); const partialData = this.resolvePartialData(request.header(HEADERS.INERTIA_PARTIAL_DATA)); const partialDataComponentHeader = request.header(HEADERS.INERTIA_PARTIAL_DATA_COMPONENT); const requestAssetVersion = request.header(HEADERS.INERTIA_VERSION); - const props: ResponseProps = await this.resolveProps( - { ...Inertia.sharedData, ...responseProps }, + const props: T = await this.resolveProps( + { ...Inertia.sharedData, ...Object(responseProps) }, partialData, component, partialDataComponentHeader, From 58607866bc5afea96988b23e1760c3b492888d0b Mon Sep 17 00:00:00 2001 From: Cody Tooker Date: Tue, 7 Mar 2023 09:57:18 -0600 Subject: [PATCH 2/2] feat(types): add InertiaPage to readme --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3e418fd..b4cc94c 100644 --- a/README.md +++ b/README.md @@ -121,14 +121,18 @@ export default class UsersController { users, lazyProp: Inertia.lazy(() => { return { lazy: 'too lazy' }; - }) + }), }); } } ``` + The data will be loaded on demand by the explicit Inertia visit with option + ```typescript -{ only: ['lazyProp']} +{ + only: ['lazyProp']; +} ``` ## Root template data @@ -210,6 +214,40 @@ Route.inertia('about', 'About'); Route.inertia('about', 'About', { metadata: '...' }); ``` +## TypeScript Helpers + +### InertiaPage + +Manually typing your front-end components can be tedious and error-prone. This is where the `InertiaPage` type comes in handy. + +If you have a controller similar to the following example: + +```typescript +import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; +import { InertiaPage } from '@ioc:EidelLev/Inertia'; + +export default class FooController { + public async index({ inertia }: HttpContextContract) { + return inertia.render('Foo', { + bar: 'FooBar', + }); + } +} + +// Export this type to use in your front-end components +export type FooIndexProps = InertiaPage; +``` + +You can then use the `FooIndexProps` type in your front-end component and get type safety for your props that will update automatically if you change the controller method response params. + +```typescript +import type FooIndexProps from 'App/Controllers/FooController'; + +const FooPage = ({ bar }: FooIndexProps) => { + return
{bar}
; +}; +``` + ## Redirects ### External redirects