withastro / language-tools

Language tools for Astro
MIT License
272 stars 54 forks source link

Typescript cannot resolve Vue Components (imported from a library) in Astro files #649

Open leifmarcus opened 1 year ago

leifmarcus commented 1 year ago

Astro Info

Astro                    v3.0.13
Node                     v18.16.0
System                   macOS (arm64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             pcom-astro-vite-config
                         @astrojs/partytown
                         @astrojs/vue

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

When importing a Vue component from a package/library, that is build width the vite library mode and has types declared with the vite-plugin-dts, then astro files cannot resolve the types for the props of the Vue component.

Instead, a type error is shown:

Type '{ testProp: string; }' is not assignable to type 'IntrinsicAttributes'.
  Property 'testProp' does not exist on type 'IntrinsicAttributes'

The type declaration for this file looks like this (automatically generated during lib build):

import type { PropType } from 'vue';
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
    testProp: {
        type: PropType<'test'>;
        default: string;
    };
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
    testProp: {
        type: PropType<'test'>;
        default: string;
    };
}>>, {
    testProp: 'test';
}, {}>, {
    default?: (_: {}) => any;
}>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
    new (): {
        $slots: S;
    };
};

A temporary fix for this is to whitelist all IntrinsicAttributes in astroHTML.JSX, which will not break the typescript check, but is not really type safe.

declare namespace astroHTML.JSX {
  interface IntrinsicAttributes {
    // [key: string]: any;
  }
}

What's the expected result?

Astro files should be able to correctly interpret the typescript typings for imported Vue files with correct types for the Vue component properties.

This should also work for Vue Components, that are not imported from Vue SFC Files, but also when imported from build javascript files.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-dggmu9

Participation

Princesseuh commented 1 year ago

The ecosystem is kinda not well setup for this... The types it generates are all super Vue and Vue tooling specific. The same issue happens with Svelte. I'm not sure what's the best way to approach this at the moment.

leifmarcus commented 1 year ago

Hello @Princesseuh, the vue typings are really hard to reason about, you are right. Thank you for looking into this issue.

ryanjwilke commented 1 year ago

I believe I was having issues with this too recently where my TypeScript checks were failing on a Tag component. It was complaining that I was passing a string into the size property, yet that's was expected behavior. The code roughly looked like this:

<Tag size="24">{ label }</Tag>

As a workaround, I just removed the component and used static HTML since it was a rather simple component, but it would be nice to have this fixed as I felt like I had to introduce some tech debt in order to get around this issue.

Psycarlo commented 10 months ago

Having the same problem

leifmarcus commented 5 months ago

@Princesseuh, I was thinking, the type problems might be because of a wrong typescript setup somehow? I think it would be great to have an example setup for typescript that works in the documentation. I remember, that in lower versions of Astro we needed to setup some typescript to make it work. I could imagine, that this setup might be the problem. But I also couldn’t find how typescript needs to be set up when using Astro with vue so that it can work with Vue and Astro files. Maybe someone has some insights about the ideal Typescript setup?

Princesseuh commented 5 months ago

@Princesseuh, I was thinking, the type problems might be because of a wrong typescript setup somehow? I think it would be great to have an example setup for typescript that works in the documentation. I remember, that in lower versions of Astro we needed to setup some typescript to make it work. I could imagine, that this setup might be the problem. But I also couldn’t find how typescript needs to be set up when using Astro with vue so that it can work with Vue and Astro files. Maybe someone has some insights about the ideal Typescript setup?

The problem in the OP is just that we don't (and honestly kinda cannot) really use the .d.ts generated by Vue, as the code they generate is specific to their tooling.

No config changes can fix this, and there're no config changes required to use Astro and Vue together, as far as I'm aware

leifmarcus commented 5 months ago

Thanks @Princesseuh. I agree. I think with the latest versions of all extensions and packages it works as expected.