Subscribe on changes!

Dynamic component event type error

avatar
Apr 15th 2022

Version

3.2.31

Reproduction link

https://sfc.vuejs.org/

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.

avatar
Oct 8th 2022

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.

avatar
Jun 25th 2023

My code with this issue runs fine. I think it might be a tooling problem. JetBrains discusses it here:

https://youtrack.jetbrains.com/issue/WEB-60065/Vue3-dynamic-component-type-mismatch-errors-when-using-component-ref-as-is-prop-value

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" />
avatar
Jun 25th 2023

I think this problem no longer exists because volar supports type-checking dynamic components now.

@juzser @qinlinwang Could you please confirm?

avatar
Jun 26th 2023

@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.

avatar
Jun 26th 2023

@juzser I tested locally and this problem does not occur. 😄

avatar
Sep 2nd 2023

/cc @edison1105 @sxzz - Close this issue?