inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.3k stars 423 forks source link

Typescript errors on createInertiaApp resolve #1770

Open webdevnerdstuff opened 8 months ago

webdevnerdstuff commented 8 months ago

Version:

Describe the problem:

Typescript errors on createInertiaApp resolve.

Steps to reproduce:

This will replicate in a new app (ex pnpm create vite).

  1. Add the setup code via the docs into a typescript file:
    createInertiaApp({
    resolve: name => {
    const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
    return pages[`./Pages/${name}.vue`]
    },
    setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
    },
    })
  2. Notice that there is a type error on the resolve.
    Type '(name: string) => unknown' is not assignable to type '(name: string) => DefineComponent | Promise<DefineComponent> | { default: DefineComponent; }'.
    Type 'unknown' is not assignable to type 'DefineComponent | Promise<DefineComponent> | { default: DefineComponent; }'.ts(2322)
    createInertiaApp.d.ts(6, 5): The expected type comes from property 'resolve' which is declared here on type 'CreateInertiaAppProps'
  3. You can set the type via
    
    import { createApp, h } from 'vue';
    import type { DefineComponent } from 'vue';
    import { createInertiaApp } from '@inertiajs/vue3';

createInertiaApp({ resolve: name => { const pages = import.meta.glob('./Pages/*/.vue', { eager: true }); return pages[./Pages/${name}.vue] as Promise; }, setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .mount(el); }, });


4. We should not need to import the `DefineComponent` type to correct this, it should just be typed correctly so the end user does not need to make adjustments to the code you provide on your site. I found this solution through this issue: https://github.com/inertiajs/inertia/issues/1372

It would also be nice if you had any kind of documentation on your site that deals with typescript, especially since Laravel pushes Inertia. With this you could just include ` Promise<DefineComponent>` and wouldn't need to refactor any code.
<!--
  Please carefully explain the steps to reproduce this issue.
  We can't help you without a reproduction.
-->
RobertBoes commented 8 months ago

Don't think this is an issue with Inertia, as Inertia does have the correct types. The issue is the glob call you're using, since it doesn't have any type, I guess Vite/TS basically doesn't know what is supposed to be imported. IIRC you'd add a generic to the glob import, something like import.meta.glob<DefineComponent>('./Pages/**/*.vue')

webdevnerdstuff commented 8 months ago

I already put the solution in my initial post.

The issue is that straight out of the box, users are going to get this error which will require spending time looking into what is wrong. I personally had this error quite a while ago, but didn't find a solution initially so made a note to come back to it later in the hopes Inertia would add some kind of typescript documentation on their site, or finding it buried into the Issues here. A package/product should start with no errors on a clean project, not require spending time problem solving something with an easy solution to implement (update the docs).

Again this is something that could be easily solved without code changes by having this in the documentation. which from the looks of it hasn't been updated in quite a while. When a large backend like Laravel is pushing it, the documentation should get at least a little bit of attention when it comes to typescript.

irshadahmad21 commented 7 months ago

1794 should fix this.

The reason for that TS error are the incorrect types which the above PR fixes.