withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
47.29k stars 2.51k forks source link

🐛 BUG: VSCode Incorrectly Marking Action with JSON as an Error (Expecting FormData) #12254

Open robertsosinski opened 1 month ago

robertsosinski commented 1 month ago

Describe the Bug

I am using the action add configured for JSON input (the default) in the add_test.astro file. See below:

actions/index.js

import {defineAction} from 'astro:actions';
import {z} from "astro:schema";

export const server = {
    add: defineAction({
        input: z.object({
            x: z.number(),
            y: z.number()
        }),
        handler: async ({x, y}) => {
            let sum = x + y;
            return {sum};
        }
    })    
};

add_test.astro

<app-complex-time>
    <button>click</button>
    <div class="target"></div>
</app-complex-time>

<script>
    import {actions} from "astro:actions";

    class AppComplexTime extends HTMLElement {
        async connectedCallback() {
            const button = this.querySelector('button');
            const target = this.querySelector('div.target');

            button.addEventListener('click', async () => {
                let input = {x: 1, y: 2};

                const { data, error } = await actions.add(input);

                if (error) {
                    target.innerHTML = "error";
                } else {
                    target.innerHTML = data.sum.toString();
                }
            });
        }
    }
    customElements.define('app-complex-time', AppComplexTime);
</script>

The problem is in VSCode on the statement actions.add(input), I get the following error:

Argument of type '{ x: number; y: number; }' is not assignable to parameter of type 'FormData'.
  Type '{ x: number; y: number; }' is missing the following properties from type 'FormData': append, delete, get, getAll, and 7 more.ts(2345)

In client components, I have no problems using JSON actions, this seems to only be an issue with .astro files requiring all actions use FormData.

Steps to Reproduce

Just make a Astro project with this action and this page. VSCode will show a red underline for actions.add(input) and report an error.

Link to Minimal Reproducible Example

https://gist.github.com/robertsosinski/ccbcd40d2235e30e68817748784170f7

robertsosinski commented 1 month ago

Attaching a screen snip to showcase how this looks for me.

Screenshot 2024-10-17 at 4 09 09 PM
Princesseuh commented 1 month ago

This is most definitely not a bug with the language server or the extension, we don't mess with types like this. I'll move this to the main repo so we can investigate if the types are wrong perhaps or if something else is going on.

robertsosinski commented 1 month ago

Sounds good @Princesseuh was not sure if this was Astro core related, as this error shows up in VSCode but this code runs totally fine. Not a blocker, but annoying to see red banners on my editor.

Would you have any idea how I could suppress this error in the meantime?

Thanks so much!

Princesseuh commented 1 month ago

You can use ts ignore comments, like // @ts-ignore on the line before

robertsosinski commented 1 month ago

Thanks, that was what I really needed for now. Have a great one!

JusticeMatthew commented 1 month ago

Some additional info for this that I don't want to get lost in discord

I have the same issue, mine is resolved by explicitly telling the action what to expect with accept: "json" The example I checked was also in a react component with the client:only="react" directive

Let me know if there is more I can do to help 👍

robertsosinski commented 1 month ago

Thanks for the extra input on this @JusticeMatthew. FYI, I also have no errors reported using actions in client components, only when using them in .astro templates. Funny enough, if I mark the script is:inline the error goes away, but that will fail as an inline script is unable to call import {actions} from "astro:actions";.

I assume its because it is an Astro template, it is going through the TypeScript checker, and even though JSON is the default, perhaps there is just a type constraint that still only lists FormData as the only output?

Again, not a blocker as it works, and I can now suppress the erroneous error. But, it adds some friction to using actions in custom web components ala https://docs.astro.build/en/guides/client-side-scripts/#web-components-with-custom-elements