language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

Template ref type inference is incompatible for components with `defineEmits` and VueUse composables

Open romansp opened this issue 11 months ago • 3 comments

Vue - Official extension or vue-tsc version

2.2.0

VSCode version

N/A

Vue version

3.5.13

TypeScript version

5.7.3

System Info

N/A

package.json dependencies

"dependencies": {
  "@vueuse/core": "^12.5.0",
  "vue": "^3.5.13"
},
"devDependencies": {
  "@types/jsdom": "^21.1.7",
  "@vitejs/plugin-vue": "^5.2.1",
  "@vue/tsconfig": "^0.7.0",
  "typescript": "^5.7.3",
  "vite": "^6.0.11",
  "vue-tsc": "^2.2.0"
}

Steps to reproduce

  1. Open provided minmal repro on stackblitz
  2. Create another terminal window
  3. Execute npm run type-check command

What is expected?

type-check script completes without errors.

What is actually happening?

type-check script fails with the following error

src/App.vue:7:37 - error TS2345: Argument of type 'Readonly<ShallowRef<CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}> | null>>' is not assignable to parameter of type 'MaybeComputedElementRef<MaybeElement>'.
  Type 'Readonly<ShallowRef<CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}> | null>>' is not assignable to type 'ShallowRef<MaybeElement, MaybeElement>'.
    Type 'Readonly<ShallowRef<CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}> | null>>' is not assignable to type 'Ref<MaybeElement, MaybeElement>'.
      Types of property 'value' are incompatible.
        Type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}> | null' is not assignable to type 'MaybeElement'.
          Type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>' is not assignable to type 'MaybeElement'.
            Type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>' is not assignable to type 'VueInstance'.
              Type 'CreateComponentPublicInstanceWithMixins<ToResolvedProps<{}, { eventName: () => any; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>' is not assignable to type '{ $: ComponentInternalInstance; $data: {}; $props: {}; $attrs: Data; $refs: Data; $slots: Readonly<InternalSlots>; $root: ComponentPublicInstance<...> | null; ... 7 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (args_0: R, args_1: R, args_2: OnClean...'.
                Types of property '$emit' are incompatible.
                  Type '(event: "eventName") => 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 '"eventName"'.

7 const bounding = useElementBounding(component);
                                      ~~~~~~~~~


Found 1 error in src/App.vue:7

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-ypjynt2e?file=src%2FApp.vue,src%2FComponent.vue

Any additional comments?

Current workaround is to import MaybeElementRef type from vueuse and cast the value.

import { type MaybeElementRef } from "@vueuse/core";
useElementBounding(component as MaybeElementRef);

Removal of defineEmits also removes type-check error.

I'm not exactly sure what's causing it and maybe vue-tsc is correct here. Though decided to start an issue here to investigate at the highest level first. If this turns out to be upstream issue at VueUse or even vue - I will reopen there.

romansp avatar Jan 30 '25 22:01 romansp

It should be a upstream issue.

Image

KazariEX avatar Jan 31 '25 05:01 KazariEX

Okay, thank you @KazariEX. I'll open an issue in VueUse repo then.

Up to you if you wanna keep this one open until it's fixed or close right away.

romansp avatar Jan 31 '25 06:01 romansp

@romansp, were you able to resolve this issue? I commented on a related issue in VueUse repo but they closed it. This isn't a Vue2 issue.

FaitAccompli avatar Feb 03 '25 14:02 FaitAccompli