defineCustomElement type error when component defines emit and imports other component
Vue version
3.2.47
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-jbymki?file=src/index.ts
Steps to reproduce
- Set up a new vue project using typescript and vite
- Create two minimal SFC components with lang="typescript"
- In one component import the other and define any emit using defineEmits and type declaration
- Create an index.ts and call defineCustomElement with the component from the step before
- execute vue-tsc
What is expected?
No error
What is actually happening?
src/index.ts:4:35 - error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, { click: () => void; }, string, PublicProps, Readonly<...> & { ...; }, {}>' is not assignable to parameter of type 'new (...args: any[]) => ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}, {}, string>, {}>'.
Type '{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<Readonly<ExtractPropTypes<{}>> & { onClick?: (() => any) | undefined; } & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>; ... 10 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any...' is not assignable to type 'ComponentPublicInstance<{}, {}, {}, {}, {}, {}, {}, {}, false, ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}, {}, string>, {}>'.
Type '{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<Readonly<ExtractPropTypes<{}>> & { onClick?: (() => any) | undefined; } & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>; ... 10 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any...' is not assignable to type '{ $: ComponentInternalInstance; $data: {}; $props: {}; $attrs: Data; $refs: Data; $slots: Readonly<InternalSlots>; $root: ComponentPublicInstance<...> | null; ... 6 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (args_0: R, args_1: R) => any : (...ar...'.
Types of property '$emit' are incompatible.
Type '(event: "click") => void' is not assignable to type '(event: string, ...args: any[]) => void'.
Types of parameters 'event' and 'event' are incompatible.
Type 'string' is not assignable to type '"click"'.
4 const Comp1 = defineCustomElement(Comp1Vue);
~~~~~~~~
node_modules/@vue/runtime-dom/dist/runtime-dom.d.ts:54:25
54 export declare function defineCustomElement(options: {
~~~~~~~~~~~~~~~~~~~
The last overload is declared here.
Found 1 error in src/index.ts:4
System Info
No response
Any additional comments?
This might be an issue related to vue-tsc
.
But judging by the referenced files in the error message, I assume that this type-error resides in the vue codebase.
Context: We want to create a component library that provides Vue and web components.
I think the issue is that Comp2 doesn't use TS, so it is interpreted as a JS file for TSC.
You have two options here:
- Set
"allowJs": true
intsconfig.json
's compilerOptions - or add an empty script block to set the language to "ts".
<template><div></div></template>
<script setup lang="ts"></script>
I think the issue is that Comp2 doesn't use TS, so it is interpreted as a JS file for TSC.
You have two options here:
1. Set `"allowJs": true` in `tsconfig.json`'s compilerOptions 2. or add an empty script block to set the language to "ts".
<template><div></div></template> <script setup lang="ts"></script>
@LinusBorg Unfortunately not... I updated the stackblitz.
I downloaded the repo, and it works fine locally with either of those changes. Though I needed to bust the cache by adding a blank line and saving Comp1.vue or something similar.
Edit: Seems to be a problem with vue-tsc. Works fine in the IDE with the changes I propsed, but vue-tsc still fails. That level of instability means its in Volar, I'd say.
Red squiggles:
No red squiggles:
... but still failing vue-tsc:
Thanks for clarifiying! I created a new issue at https://github.com/vuejs/language-tools/issues/2450
This is defineCustomElement problem, here is minimal reproduction.
Instability is another TypeScript issue that can be reproduced in tsc
with the following .ts content.
index.ts
import { defineCustomElement } from 'vue';
import Comp1Vue from './Comp1.vue';
defineCustomElement(Comp1Vue);
Comp1.vue.ts
import Comp2 from './Comp2.vue'; // remove this line, tsc error goes away
export default (await import('vue')).defineComponent({
emits: ({} as {
click(): void;
})
})
Comp2.vue.ts
export default (await import('vue')).defineComponent({});