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

How to use with typescript? #160

Closed
zoeleu opened this issue Jul 12, 2021 · 12 comments
Closed

How to use with typescript? #160

zoeleu opened this issue Jul 12, 2021 · 12 comments

Comments

@zoeleu
Copy link

zoeleu commented Jul 12, 2021

How do I use 'import' with typescript?

@sprabowo
Copy link

@matteoturini
just tried this one (might not be the best solution)

// @ts-ignore
import srcsetWebp from '../example.jpg?w=500;700;900;1200&webp&srcset'

@zoeleu
Copy link
Author

zoeleu commented Sep 21, 2021

@matteoturini
just tried this one (might not be the best solution)

// @ts-ignore
import srcsetWebp from '../example.jpg?w=500;700;900;1200&webp&srcset'

No typing. This is not a fix. Maybe make a flag so that you have to do something like this:

import example from '../example.jpg'

Config:

images: {
  'example.jpg': 'w=500;700;900;1200&webp&srcset'
}

Mentioning @JonasKruckenberg

@jugglingcats
Copy link
Contributor

You can also create a file, eg. typings.d.ts in your project with:

declare module "*.jpg?w=500;700;900;1200&webp&srcset"

Not ideal if you have a lot of different formats, but...

@JonasKruckenberg
Copy link
Owner

Yeah, there are a lot of less than ideal solutions to this problem, not much we can do from our side. The real fix is to lobby the typescript guys to allow multiple * in module declarations or allow search params to occur in any order.
But until then, presets will ease this a bit.

@zoeleu
Copy link
Author

zoeleu commented Nov 6, 2021

Yeah, there are a lot of less than ideal solutions to this problem, not much we can do from our side. The real fix is to lobby the typescript guys to allow multiple * in module declarations or allow search params to occur in any order. But until then, presets will ease this a bit.

Yes, TypeScript could do that. But until then, is it possible to make importing with the config as I mentioned before?

@JonasKruckenberg
Copy link
Owner

JonasKruckenberg commented Nov 10, 2021

A config object like you proposed will not be implemented. It's actually the exact thing that motivated this project. It'd should be obvious from looking at your source code what transformations are applied to your image instead of it being a declared somewhere else and applied "magically".
However, using the updated defaultDirectives you can implement type-able presets:

imagetools({
   defaultDirectives: id => {
      if (id.searchParams.has('hero')) { // the `hero` directive was set on the image
         return new URLSearchParams('width=1200;900;800&avif&metadata')
      }
      return new URLSearchParams()
   }
})

You can then type the preset:

declare module '*.jpg?hero' {
   const image: Record<string, any>
   export default image
}

I'm sorry if this is disappointing to you, but exactly the feature you asked for was the annoyance I experienced with the webpack-responsive-loader (they seem to also support url directives now!) and will therefore not be part of this plugin. I know that this type issue is super annoying; everything is a tradeoff however, and I feel that manual typing is still the better DX than "magic image transformation"

@JonasKruckenberg
Copy link
Owner

JonasKruckenberg commented Nov 10, 2021

However, using the updated defaultDirectives you can implement type-able presets:

This got released in vite-imagetools@4.0.0 and rollup-plugin-imagetools@3.0.0 respectively.
I feel like this provides enough workarounds for the use in typescript so I'll close this for now. Feel free to reopen if the situation changes!

@zoeleu
Copy link
Author

zoeleu commented Nov 10, 2021 via email

@benblazak
Copy link

as another workaround, for anyone else finding this

rather than create a preset without values, i added

declare module "*&imagetools" {
  /**
   * actual types
   * - code https://github.com/JonasKruckenberg/imagetools/blob/main/packages/core/src/output-formats.ts
   * - docs https://github.com/JonasKruckenberg/imagetools/blob/main/docs/guide/getting-started.md#metadata
   */
  const out;
  export default out;
}

to my globals.d.ts (i'm using sveltekit), and then added &imagetools to the end of my imports, e.g.

import image from "$lib/assets/image.jpg?w=200;400&format=webp;png&meta&imagetools";

imagetools seems to happily ignore the extra query parameter.

this is a bit verbose, but i liked it better than not being able to specify values.

also, one could add specific typing this way, e.g. by

declare module "*&meta&imagetools" {
  ...
}

@b-lov
Copy link

b-lov commented Feb 21, 2022

thats an awesome and creative solution, thanks!

@gnuion
Copy link

gnuion commented Jul 13, 2023

With the plugin configured as follows, the imported image ending with ?gallery returns an array of two objects.

imagetools({
  defaultDirectives: (id) => {
    if (id.searchParams.has("gallery")) {
      return new URLSearchParams("w=300;600&format=webp&as=metadata");
    }
    return new URLSearchParams();
  },
}),
import sampleImage from "@/assets/images/sample_image.jpeg?gallery";
console.log(sampleImage);

Output
image

You then can define the type for the values of interest.

declare module "*?gallery" {
  const images: {
    width: string;
    src: string;
  }[];
  export default images;
}

Now, as you can see, you can access the low res image as sampleImage[0].src and high res with sampleImage[1].src

@albehrens
Copy link

Imagetools can return:

  • A string
  • An array of strings
  • An object
  • An array of objects

I have updated my types like this to reflect that. You know best what type of import to use in your application:

interface OutputMetadata {
    src: string; // URL of the generated image
    width: number; // Width of the image
    height: number; // Height of the image
    format: string; // Format of the generated image

    // The following options are the same as sharps input options
    space: string; // Name of colour space interpretation
    channels: number; // Number of bands e.g. 3 for sRGB, 4 for CMYK
    density: number; //  Number of pixels per inch
    depth: string; // Name of pixel depth format
    hasAlpha: boolean; // presence of an alpha transparency channel
    hasProfile: boolean; // presence of an embedded ICC profile
    isProgressive: boolean; // indicating whether the image is interlaced using a progressive scan
}

declare module "*&as=metadata&imagetools-gallery" {
    const outputs: Array<OutputMetadata>;
    export default outputs;
}

declare module "*&as=metadata&imagetools" {
    const outputs: OutputMetadata;
    export default outputs;
}

declare module "*&imagetools-gallery" {
    const outputs: Array<string>;
    export default outputs;
}

declare module "*&imagetools" {
    const outputs: string;
    export default outputs;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants