withastro/language-tools

๐Ÿ› BUG: Images assets imported in tsx files have the wrong type.

EthanShoeDev opened this issue ยท 2 comments

Describe the Bug

Images imported in *.astro files automatically have the ImageMetadata type.
Images imported in *.tsx files have an any type.

Disabling the astro vscode extension fixes the type in tsx files so that image imports have the ImageMetadata type.

Steps to Reproduce

  1. npm init astro using options:
~/temp$ npm init astro

 astro   Launch sequence initiated.
   dir   Where should we create your new project?
         ./gh-issue
  tmpl   How would you like to start your new project?
         Empty
    ts   Do you plan to write TypeScript?
         Yes
   use   How strict should TypeScript be?
         Strictest
  deps   Install dependencies?
         Yes
   git   Initialize a new git repository?
         No
      โ—ผ  Sounds good! You can always run git init manually.
  1. Add the image src/assets/blog-header.jpg
    blog-header

  2. Add react integration

npx astro add react
  1. Add a dummy react component: src/components/example.tsx
import blogHeaderImg from "../assets/blog-header.jpg";

export function Example() {
  return <img src={blogHeaderImg.src} />;
}
  1. Modify src/pages/index.astro
import { Example } from "../components/example";
import blogHeaderImg from "../assets/blog-header.jpg";
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>Astro</title>
  </head>
  <body>
    <h1>Astro</h1>
    <Example />
    <img src={blogHeaderImg.src} />
  </body>
</html>
  1. Error, expected blogHeaderImg to be ImageMetadata type in both index.astro and example.tsx

In index.astro
image

In example.tsx
image

In example.tsx after disabling Astro vscode extension.
image

After some investigating I found that commenting out this line fixes the issue.

image

This really just confirms that the ts-plugin is to blame. I am not sure if this is an issue in volar.js or in astro language tools.
I would like to setup a minimum viable volar.js typescript plugin to confirm if it is in upstream but I can't really find any docs on this function:

import { createLanguageServicePlugin } from '@volar/typescript/lib/quickstart/createLanguageServicePlugin.js';

All the volar.js docs I have found do not include the ts-plugin piece.

And another bit of information I found really strange.

Looking at this line in the example.tsx file:

import blogHeaderImg from "../assets/blog-header.jpg";

If I right-click on the "../assets/blog-header.jpg" both "Go to Definition" and "Go to Type Definition" is able to find the correct ImageMetadata type defined at node_modules/astro/client.d.ts

declare module '*.jpg' {
	const metadata: ImageMetadata;
	export default metadata;
}

However, if I right-click on the blogHeaderImg part, "Go to Definition" still takes me to the correct definition but "Go to Type Definition" shows the error:
No type definition found for 'blogHeaderImg'.
image