Dynamic component event type error
Version
3.2.31
Reproduction link
Steps to reproduce
If I use event in dynamic component as below:
// Parent component
<component :is="foo" @change="handleChange">
<script setup>
const emits = defineEmits<{
(e: 'change', value: string, id: string): void;
}>();
const handleChange = (value: string, id: string) => {
...
}
</script>
In the child component, emit the value and id.
What is expected?
Avoid typescript error on build.
What is actually happening?
I will get the typescript error:
error TS2322: Type '(value: string, id: string) => void' is not assignable to type '(payload: Event) => void'.
I think, it's because of when you use dynamic component <component :is...>
all the emit events will be understood as default events, and the params type should be Event
.
I have the similar problem. I defined a native event (e.g., input) in the emits option:
// Home.vue
<template>
<div
class="tab"
contenteditable="true"
@input="handleInput"
>
Home component
</div>
</template>
<script setup lang="ts">
// 为组件的 emits 标注类型
const emit = defineEmits<{
(e: 'input', id: Object, value: string): void
}>();
function handleInput(e:Event) {
emit("input", "props.element", (e.target as Element).innerHTML);
}
</script>
and use it in App.vue
<script setup lang="ts">
import Home from './Home.vue'
// som code ...
function handleInput(a: any, b: string){
console.log(`b: ${b}`);
}
</script>
<template>
<component :is="tabs[currentTab]" class="tab" @input="handleInput"></component>
</template>
the code can run online, but will report error in vscode:
Type '(a: any, b: string) => void' is not assignable to type '(payload: Event) => void'.
The expected type comes from property 'input' which is declared here on type 'EventObject<any, "input", {}, unknown, ((payload: Event) => void) | undefined>'
Vue version
3.2.40
Reproduction link
code can run in the link, but it will report error in vscode. Reproduction link
What is expected?
Avoid typescript error.
My code with this issue runs fine. I think it might be a tooling problem. JetBrains discusses it here:
And Vue language tools for VSCode here:
https://github.com/vuejs/language-tools/issues/3138 https://github.com/vuejs/language-tools/issues/3237
You can make it go away for the time being with something like:
<component :is="foo as any" />
I think this problem no longer exists because volar supports type-checking dynamic components now.
@juzser @qinlinwang Could you please confirm?
@so1ve That's right, volar supports dynamic components type-checking now so I guess it no longer occurs. But I'm not sure 100%, I've not tested.