Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@astrojs/image overrides import type for images (including code in other frameworks like react) #5924

Closed
1 task
JLarky opened this issue Jan 21, 2023 · 10 comments
Assignees
Labels
pkg: image Related to the `@astrojs/image` package (scope)

Comments

@JLarky
Copy link
Contributor

JLarky commented Jan 21, 2023

What version of astro are you using?

1.9.2

Are you using an SSR adapter? If so, which one?

No

What package manager are you using?

npm

What operating system are you using?

Mac

Describe the Bug

importing images in React gives typescript error because @astrojs/image overrides the type (but not value) from string to ImageMetadata

code:

import logo from './dummy.png';

export default function Counter() {
  // img is expecting a string but we get ImageMetadata type instead
  return (
      <img src={logo} />
  );
}

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-xdmbqd?file=src/components/Counter.tsx

Participation

  • I am willing to submit a pull request for this issue.

Update

Thanks for @aFuzzyBear message in discord that fixes this issue by adding ?url in image import

import logo from './dummy.png?url'; // ?url makes sure that import is a string

export default function Counter() {
  return (
      <img src={logo} />
  );
}
@bluwy
Copy link
Member

bluwy commented Jan 22, 2023

The value should be of shape ImageMetadata if you pass the image() in the Astro config. If you're not using the integration intentionally, then you probably shouldn't reference the images types in the env.d.ts file, which should fix it.

@JLarky
Copy link
Contributor Author

JLarky commented Jan 22, 2023

The value should be of shape ImageMetadata if you pass the image() in the Astro config. If you're not using the integration intentionally, then you probably shouldn't reference the images types in the env.d.ts file, which should fix it.

This example was intentionally simplified. In a real project I use astro image in astro files, but it messes up with stuff in React files now. So if I remove those types to fix React now I will have the error in Astro

@bluwy
Copy link
Member

bluwy commented Jan 22, 2023

Maybe we could make the image integration to work in .astro and .mdx files only. But it's still not possible to type .png etc imports differently depending if you're in an .astro file or .tsx file, since TypeScript only allows you to define one.

Maaaybe you can create 2 tsconfigs, one targets .astro files and the env.d.ts (with @astrojs/image/client); the other targets the rest without the env.d.ts, and TypeScript might be able to type the import differently then.

@JLarky
Copy link
Contributor Author

JLarky commented Jan 24, 2023

Okay :) it turned out to be a bit more sinister than I thought :) it does indeed change import shape for react as well as for astro files :) I was testing my react wrong. So the issue isn't that types do not match, the issue is that image integration changes image imports for React :)

@matthewp
Copy link
Contributor

I'm not sure if there's anything we can do here, but someone will take a look.

@JLarky
Copy link
Contributor Author

JLarky commented Jan 27, 2023

if someone can test this behavior in other rendering frameworks that could be very helpful

@Princesseuh
Copy link
Member

This is currently intended that the integration changes the shape of the ESM import in the entire project. In the future when the image integration will be merged inside core, we expect for this shape (or a similar one) to be the default

Apart from documentation being unclear on this, does this cause any issue? You can do image.src to get a path to show the image in a img tag

@JLarky
Copy link
Contributor Author

JLarky commented Jan 28, 2023

I'm using Astro to power an existing application (40kloc typescript/react) so it overall requires a bit more consideration than a new greenfield project :) luckily it uses typescript so it was easy to find where assets got broken, but not everyone could be as lucky, especially if those types are changing over time (like in our case, when we started using @astro/image)

And yes, currently I'm using image.src, but it's complicated by the fact that the same code can run outside of Astro (where import would return just string, thus some confusion in the original post). Here's what I actually do:

function fixImgSrc(src: ImageMetadata | string) {
  return typeof src === "string" ? src : src.src;
}

I think this issue could be resolved by improvements in the documentation. I wish I had an idea for a simpler solution :) I'm a bit new to all that bunder (and loader) magic :)

@JLarky JLarky changed the title @astrojs/image/client types override what react expects @astrojs/image overrides import type for images (including code in other frameworks like react) Jan 31, 2023
@JLarky
Copy link
Contributor Author

JLarky commented Jan 31, 2023

Thanks for @aFuzzyBear message in discord that fixes this issue by adding ?url in image import

https://stackblitz.com/edit/github-xdmbqd-hbxzkd?file=src%2Fcomponents%2FCounter.tsx

import logo from './dummy.png?url'; // ?url makes sure that import is a string

export default function Counter() {
  return (
      <img src={logo} />
  );
}

I think this issue could be resolved by documenting this workaround in docs

@Princesseuh
Copy link
Member

Closing since this is intended, we'll document this better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: image Related to the `@astrojs/image` package (scope)
Projects
None yet
Development

No branches or pull requests

4 participants