Properly typing web component created via defineCustomElement
Vue version
3.3.4
Link to minimal reproduction
https://stackblitz.com/edit/vue3-vite-typescript-starter-juvyz7?file=src%2FApp.vue
Steps to reproduce
Using volar, if you hover over registered test-component (being a custom element) hints and strict types are only working if you manually cast the custom element to an original vue component (using the globals in components.d.ts).
What is expected?
Result of the defineCustomElement should be able to be direcly assigned as a type and template should provide correct typehints via volar.
What is actually happening?
So i have a need to use custom elements built via vue3 in our legacy vue 2, and for that purpose i decided to use defineCustomElement feature which is working great overall but typings are a bit odd or maybe i dont know how to better approach this.
Right now, if i try to declare globals using the result of the defineCustomElement, there is no autocomplete and type hints in the template. I have to directly use the original vue component which in my opinion is a bit odd. Is there a way to better approach this problem?
Other questiong is how to properly deal with the events. Right now, i've come up with this solution: const emit = defineEmits<{ (event: "update:selectedOption", value: CustomEvent<[string]>): void }>();
which is also suboptimal in my opinion.
Thank you.
System Info
No response
Any additional comments?
No response
@GabrielHangor it seems to be working, I've pulled your example and ran locally and seems to work
steps
> download the project
> `pnpm i`
> change `selectedOption` to number on App.vue
Playground it should error, but is not.
This is most likely caused by language tools instead of vue/core.
Other questiong is how to properly deal with the events. Right now, i've come up with this solution: const emit = defineEmits<{ (event: "update:selectedOption", value: CustomEvent<[string]>): void }>(); which is also suboptimal in my opinion.
You can use object based
const emit = defineEmits({
'update:SelectedOption': (value: CustomEvent<[string]>) => true
})
or prop based:
defineProps<{
selectedOption: string,
'onUpdate:SelectedOption': (value: CustomEvent<[string]>) => void
}>
@pikax Hey Carlos, My example is working since i casted the type of the custom element to the original vue component and declared it globally (in components.d.ts). This way typechecking and hints are working exactly as expected.
But the problem is that if you cast the custom element to the custom element in GlobalComponents interface, there are no hints. So, typeof defineCustomElement(...someElement) is not suitable to be used to type it in GlobalComponents, as shown in docs...
Hope that ive explained it clearly now.
As for the second question, many thanks, sounds neat.
I've found a solution, you just have to do it like that:
Now the types can be properly obtained by volar Maybe this should be added to the docs as an example because the current one is not correct...