Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue mount type definitions error on SFCs with only one define API used #24818

Closed
JoostKersjes opened this issue Nov 25, 2022 · 9 comments · Fixed by #25538
Closed

Vue mount type definitions error on SFCs with only one define API used #24818

JoostKersjes opened this issue Nov 25, 2022 · 9 comments · Fixed by #25538
Labels
CT Issue related to component testing npm: @cypress/vue @cypress/vue package issues

Comments

@JoostKersjes
Copy link

Current behavior

Upgrading to Cypress v11 (any minor version) has resulted in TypeScript errors appearing in my component test files, specifically when using mount with an SFC that has only one of the defineProps, defineEmits and defineExpose API's used in its setup.

<script lang="ts" setup>
defineProps<{
  label: string;
}>();
</script>
  
<template>
  <button type="button" :title="label" :aria-label="label">
    <slot />
  </button>
</template>
import HelloWorld from './HelloWorld.vue'

describe('<HelloWorld />', () => {
  it('renders', () => {
    cy.mount(HelloWorld, {}) // TypeScript Error ts(2769)
  })
})
$ vue-tsc --noEmit
src/components/HelloWorld.cy.ts:6:14 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type 'ComponentPublicInstanceConstructor<{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>; ... 10 more ...; $watch<T extends string | ((...args: any) => any...' is not assignable to parameter of type 'ComponentOptionsWithObjectProps<__VLS_TypePropsToRuntimeProps<{ label: string; }>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 5 more ..., {}>'.
      Type 'ComponentPublicInstanceConstructor<{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>; ... 10 more ...; $watch<T extends string | ((...args: any) => any...' is not assignable to type 'ComponentOptionsBase<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>> & { [x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined; }, ... 10 more ..., string>'.
        Types of property 'setup' are incompatible.
          Type '((this: void, props: Readonly<LooseRequired<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>>>>, ctx: SetupContext<...>) => void | ... 2 more ... | Promise<...>) | undefined' is not assignable to type '((this: void, props: Readonly<LooseRequired<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>> & { [x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined; }>>, ctx: SetupContext<...>) => void | ... 2 more ... | Promise<...>) | undefined'.
            Type '(this: void, props: Readonly<LooseRequired<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>>>>, ctx: SetupContext<...>) => void | ... 2 more ... | Promise<...>' is not assignable to type '(this: void, props: Readonly<LooseRequired<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ label: string; }>>> & { [x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined; }>>, ctx: SetupContext<...>) => void | ... 2 more ... | Promise<...>'.
              Types of parameters 'ctx' and 'ctx' are incompatible.
                Type 'SetupContext<string[]>' is not assignable to type 'SetupContext<{}>'.
                  Type '{}' is missing the following properties from type 'string[]': length, pop, push, concat, and 29 more.

6     cy.mount(HelloWorld, {})
               ~~~~~~~~~~

  node_modules/cypress/vue/dist/index.d.ts:1339:18
    1339 declare function mount<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D extends {}, C extends ComputedOptions = {}, M extends Record<string, Function> = {}, E extends EmitsOptions = Record<string, any>, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, EE extends string = string>(componentOptions: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, E, Mixin, Extends, EE>, options?: MountingOptions<ExtractPropTypes<PropsOptions> & PublicProps, D>): Cypress.Chainable<{
                          ~~~~~
    The last overload is declared here.


Found 1 error in src/components/HelloWorld.cy.ts:6

Changing the component definition code to the follow will make the error disappear:

<script lang="ts" setup>
defineProps<{
  label: string;
}>();
defineEmits<{
  (e: "hello"): void;
}>();
</script>
  
<template>
  <button type="button" :title="label" :aria-label="label">
    <slot />
  </button>
</template>

Desired behavior

TypeScript should not throw an error when mounting a Vue SFC component with the following syntax, regardless of the component definition:

import HelloWorld from './HelloWorld.vue'

describe('<HelloWorld />', () => {
  it('renders', () => {
    cy.mount(HelloWorld, {}) // Should not throw a TypeScript error
  })
})

Test code to reproduce

Due to the similarities to #23653 that I submitted a while back, I forked the repo that @lmiller1990 graciously provided there. Turns out, all I had to do was upgrade the package versions to reproduce the error :)

https://github.com/JoostKersjes/cypress-issue-23653/tree/v11-upgrade-type-issue

Cypress Version

11.2.0 (reproducable for any version >= 11.0.0)

Node version

v16.8.0

Operating System

Kubuntu 20.04

Debug Logs

No response

Other

No response

@lmiller1990
Copy link
Contributor

I wonder why adding defineEmits fixes it?

Either way, let's fix this - I have no idea why an empty mounting options arg triggers this. Vue core changed their types a bunch recently, I wonder if that's related. Also, I wonder if Test Utils has the same issue.

@rockindahizzy
Copy link
Contributor

@rockindahizzy rockindahizzy removed their assignment Dec 6, 2022
@lmiller1990
Copy link
Contributor

Probably just need to copy+paste latest typedefs from Test Utils, or update to the latest version of Test Utils.

@mbp
Copy link

mbp commented Jan 19, 2023

This is blocking us from upgrading to TypeScript 4.9

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jan 23, 2023

I am on latest Cypress (12) TS (4.9) and Vue (3.45) and I am not able to reproduce.

EDIT I see, you need to do yarn vue-tsc --noEmit.

Can someone share a reproduction, maybe @mbp?

I fixed it #25538

@lmiller1990
Copy link
Contributor

It will be in the next release, please wait a bit. We release every two weeks.

I should have targeted master so this would have been auto-released, but I forgot, sorry about that.

@mbp
Copy link

mbp commented Mar 21, 2023

I know this issue is closed, but I want to add that after upgrading to TypeScript 5, a new type error for the emits occur (not exactly same, but seems related).

MyComponentTest.ts:12:11 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '__VLS_WithTemplateSlots<DefineComponent<__VLS_TypePropsToRuntimeProps<Props>, { isPanelOpen: Ref<boolean>; onPanelToggle: () => boolean; }, unknown, {}, {}, ComponentOptionsMixin, ... 5 more ..., {}>, { ...; }>' is not assignable to parameter of type 'ComponentOptionsWithObjectProps<__VLS_TypePropsToRuntimeProps<Props>, { isPanelOpen: Ref<boolean>; onPanelToggle: () => boolean; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, string[], string>'.
      Type '__VLS_WithTemplateSlots<DefineComponent<__VLS_TypePropsToRuntimeProps<Props>, { isPanelOpen: Ref<boolean>; onPanelToggle: () => boolean; }, unknown, {}, {}, ComponentOptionsMixin, ... 5 more ..., {}>, { ...; }>' is not assignable to type 'ComponentOptionsBase<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<Props>>> & { [x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined; }, ... 10 more ..., string>'.
        Types of property 'emits' are incompatible.
          Type 'ThisType<void> | (string[] & ThisType<void>) | undefined' is not assignable to type '(string[] & ThisType<void>) | undefined'.
            Type 'ThisType<void>' is not assignable to type 'string[] & ThisType<void>'.
              Type 'ThisType<void>' is missing the following properties from type 'string[]': length, pop, push, concat, and 31 more.

12     mount(MyComponent, {
             ~~~~~~~~~~~

  node_modules/cypress/vue/dist/index.d.ts:1339:18
    1339 declare function mount<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D extends {}, C extends ComputedOptions = {}, M extends Record<string, Function> = {}, E extends EmitsOptions = Record<string, any>, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, EE extends string = string>(componentOptions: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, E, Mixin, Extends, EE>, options?: MountingOptions<ExtractPropTypes<PropsOptions> & PublicProps, D>): Cypress.Chainable<{
                          ~~~~~
    The last overload is declared here.

@nagash77
Copy link
Contributor

Hi @mbp please open a new issue if you are encountering problem while using Cypress.

@lmiller1990
Copy link
Contributor

I will look into TS 5 support here: #26148

@mbp can you share your component/test code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CT Issue related to component testing npm: @cypress/vue @cypress/vue package issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants