vite icon indicating copy to clipboard operation
vite copied to clipboard

`ViteHotContext` type should be customizable

Open FreeJ1nG opened this issue 9 months ago • 10 comments

Describe the bug

I am trying to add custom events in addition to the current CustomEventMap, and i'd want the payload type of the custom events to be typed properly

// vite-env.d.ts (this line is not in the actual code)
/// <reference types="vite/client" />

interface CustomEventMap {
  'vite:customEvent': number;
}

export type InferCustomEventPayload<T extends string> =
  T extends keyof CustomEventMap ? CustomEventMap[T] : never;

interface ViteHotContext {
  on<T extends string>(
    event: T,
    cb: (payload: InferCustomEventPayload<T>) => void
  ): void;
}

interface ImportMetaEnv {
  readonly VITE_HI: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
  readonly hot?: ViteHotContext;
}

if (import.meta.hot) {
  import.meta.hot.on("vite:customEvent", (payload) => {});
                                             ^ expect to be number, got any
}

Reproduction

https://stackblitz.com/edit/vitejs-vite-pkygn6?file=src%2Fvite-env.d.ts

Steps to reproduce

npm install npm run dev

System Info

System:
  OS: macOS 14.4.1
  CPU: (8) arm64 Apple M2
  Memory: 134.44 MB / 8.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 21.6.2 - /opt/homebrew/bin/node
  Yarn: 1.22.19 - /opt/homebrew/bin/yarn
  npm: 10.2.4 - /opt/homebrew/bin/npm
  pnpm: 9.0.6 - /opt/homebrew/bin/pnpm
  bun: 1.1.5 - ~/.bun/bin/bun
Browsers:
  Chrome: 124.0.6367.119
  Safari: 17.4.1
npmPackages:
  @vitejs/plugin-react-swc: ^3.5.0 => 3.6.0 
  vite: ^5.2.0 => 5.2.10

Used Package Manager

npm

Logs

No response

Validations

FreeJ1nG avatar May 05 '24 07:05 FreeJ1nG

I tried changing the vite source code for HMR types to not use imports at the top level, as suggested on TS' documentation.

I'm out of ideas on how to create the proper overridable types for the HMR declaration type

FreeJ1nG avatar May 05 '24 07:05 FreeJ1nG

If you're adding custom events, have you tried this? https://vitejs.dev/guide/api-plugin.html#typescript-for-custom-events

It would be in a separate .d.ts file for it to work, which is understandably a bit odd compared to other typescript augmentations, but I think that pattern should also work.

bluwy avatar May 05 '24 10:05 bluwy

If you're adding custom events, have you tried this? https://vitejs.dev/guide/api-plugin.html#typescript-for-custom-events

It would be in a separate .d.ts file for it to work, which is understandably a bit odd compared to other typescript augmentations, but I think that pattern should also work.

Hi Bjorn,

Thanks for the reply, I definitely missed that part of the docs! my bad

I tried following the example there, here is the code

UPD: I changed the stackblitz link since the previous link used an old vite version, but it still doesn't work properly

It still casts the payload to any, I'm not quite sure if I messed something up 😅

FreeJ1nG avatar May 05 '24 10:05 FreeJ1nG

It seems it needs to be (notice the extension):

import 'vite/types/customEvent.d.ts';

declare module 'vite/types/customEvent.d.ts' {
  interface CustomEventMap {
    'custom:myCustomEvent': number;
  }
}

It seems we need the extension when "moduleResolution": "bundler" is used. I guess it's because we export it like this.

sapphi-red avatar May 06 '24 04:05 sapphi-red

It seems it needs to be (notice the extension):

import 'vite/types/customEvent.d.ts';

declare module 'vite/types/customEvent.d.ts' {
  interface CustomEventMap {
    'custom:myCustomEvent': number;
  }
}

It seems we need the extension when "moduleResolution": "bundler" is used. I guess it's because we export it like this.

That definitely fixed it!

Shall I create a PR to fix the wording in the docs? or is it not necessary?

FreeJ1nG avatar May 06 '24 05:05 FreeJ1nG

It would be great if you can do it 😀

sapphi-red avatar May 06 '24 07:05 sapphi-red

It would be great if you can do it 😀

Will do 🫡

I also think this part of the docs would be a better fit in the HMR API section rather than Plugin API, since it's a customization of the custom event type used in HMR

So here: https://vitejs.dev/guide/api-hmr.html#further-reading Instead of: https://vitejs.dev/guide/api-plugin#typescript-for-custom-events

And maybe there could be a link in api-plugin referring to the one in api-hmr

What do you think about that?

FreeJ1nG avatar May 06 '24 08:05 FreeJ1nG

Created a PR here

FreeJ1nG avatar May 06 '24 09:05 FreeJ1nG

thanks guys

jonlepage avatar May 07 '24 08:05 jonlepage

Closing as #16609 is merged.

sapphi-red avatar May 17 '24 04:05 sapphi-red