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

Is there support for Vue 3 <script setup>? #217

Closed
onx2 opened this issue Oct 3, 2020 · 13 comments
Closed

Is there support for Vue 3 <script setup>? #217

onx2 opened this issue Oct 3, 2020 · 13 comments

Comments

@onx2
Copy link

onx2 commented Oct 3, 2020

It seems to work but with this warning. Is this something that I should be asking in this repo?

Vue file

<script setup="props" lang="ts">
import { computed } from "vue"

declare const props: {
  msg: string
}

export const computedMsg = computed(() => props.msg + "!!!")
</script>

<template>
  <div>
    <h1>Example</h1>
    <span>{{ computedMsg }}</span>
  </div>
</template>

Ouput

[Vue warn]: Property "computedMsg" was accessed during render but is not defined on instance. 
      at <Anonymous ref="VTU_COMPONENT" > 
      at <VTUROOT>

       9 | </script>
      10 | 
    > 11 | <template>
         |                                         ^
      12 |   <div>
      13 |     <h1>Example</h1>
      14 |     <span>{{ computedMsg }}</span>
@lmiller1990
Copy link
Member

This will depend on your pre-processor. Are you using vue-jest? If so, it is not supported there (yet).

I can work on this soon. I made an issue to track it: vuejs/vue-jest#289

In short: not related to this repo.

@lmiller1990
Copy link
Member

lmiller1990 commented Oct 5, 2020

@onx2 I am working on this feature this week, you can see the WIP PR here: vuejs/vue-jest#290

It's basically working, just need to make sure I didn't break anything else and test a bit more. Keep an eye out; I think we can release it this week or so.

@lmiller1990
Copy link
Member

lmiller1990 commented Oct 7, 2020

@onx2 if you have some time on your hands you could help test this out. That would help me release it with more confidence. Implemented here: vuejs/vue-jest#290

@onx2
Copy link
Author

onx2 commented Oct 7, 2020

You bet. I'll be able to test it out tomorrow and will let you know

@onx2
Copy link
Author

onx2 commented Oct 7, 2020

Looks like it's working on that commit hash you linked to. Still looking into a few more things though.

Vue file
image

Test file
image

package.json
image

@onx2
Copy link
Author

onx2 commented Oct 8, 2020

So I am running into one error that I think is unrelated but wanted to post just in case. Using this TS shim:

declare module "*.vue" {
  import { defineComponent } from "vue"
  const Component: ReturnType<typeof defineComponent>

  export default Component
}

I'm getting a TS error when mounting with props:

No overload matches this call.
  The last overload gave the following error.
    Argument of type 'DefineComponent<readonly string[] | Readonly<ComponentObjectPropsOptions<Record<string, unknown>>>, unknown, unknown, Record<string, ComputedGetter<any> | WritableComputedOptions<...>>, ... 7 more ..., { ...; } | {}>' is not assignable to parameter of type 'ComponentOptionsWithObjectProps<readonly string[] | Readonly<ComponentObjectPropsOptions<Record<string, unknown>>>, unknown, unknown, Record<string, ComputedGetter<any> | WritableComputedOptions<...>>, ... 6 more ..., { ...; } | {}>'.
      Type 'DefineComponent<readonly string[] | Readonly<ComponentObjectPropsOptions<Record<string, unknown>>>, unknown, unknown, Record<string, ComputedGetter<any> | WritableComputedOptions<...>>, ... 7 more ..., { ...; } | {}>' is not assignable to type 'ComponentOptionsBase<Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; ... 17 more ...; flat?: unknown[] | undefined; }> | Readonly<...>, ... 8 more ..., { ...; } | {}>'.
        Types of property 'setup' are incompatible.
          Type '((this: void, props: Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; ... 17 more ...; flat?: unknown[] | undefined; }> | Readonly<...>, ctx: import("/home/onx2/Documents/pr...' is not assignable to type '((this: void, props: Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; ... 17 more ...; flat?: unknown[] | undefined; }> | Readonly<...>, ctx: import("/home/onx2/Documents/pr...'. Two different types with this name exist, but they are unrelated.
            Type '(this: void, props: Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; slice?: string[] | undefined; ... 16 more ...; flat?: unknown[] | undefined; }> | Readonly<...>, ctx: im...' is not assignable to type '(this: void, props: Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; slice?: string[] | undefined; ... 16 more ...; flat?: unknown[] | undefined; }> | Readonly<...>, ctx: im...'. Two different types with this name exist, but they are unrelated.
              Types of parameters 'ctx' and 'ctx' are incompatible.
                Type 'SetupContext<string[]>' is not assignable to type 'SetupContext<EmitsOptions>'.
                  Type 'EmitsOptions' is not assignable to type 'string[]'.
                    Type 'Record<string, ((...args: any[]) => any) | null>' is missing the following properties from type 'string[]': length, pop, push, concat, and 28 more.ts(2769)
mount.d.ts(34, 25): The last overload is declared here.

Changing the shim to what I have below seems to resolve the issue but I'm not sure of the expected type for the vue shim. Evan posted a while back the one I have above which is why I have it in there. I'm sure things have changed since I last checked. Do you know the expected type for the the shim?

declare module "*.vue" {
  import { defineComponent, ComponentOptionsWithObjectProps } from "vue"
  const Component: ComponentOptionsWithObjectProps<unknown>

  export default Component
}

Maybe this?

const Component: ComponentOptionsWithObjectProps<ReturnType<
    typeof defineComponent
  >>

With either of the type defs directly above, the tests pas:
image

@lmiller1990
Copy link
Member

I also have this shim issue, it is very difficult to solve due to the dynamic nature of the components that can be passed to mount.

I made this issue: #194

Basically you can do

mount(Example, {
  // ...
} as any)

To work around it.

Other than TS errors, everything is working ok?

@onx2
Copy link
Author

onx2 commented Oct 8, 2020

Aside from the TS error using the old type def, my tests are passing. ✔️

This is the type def I ended up with to prevent TS errors:

declare module "*.vue" {
  import { defineComponent, ComponentOptionsWithObjectProps } from "vue"
  const Component: ComponentOptionsWithObjectProps<ReturnType<
    typeof defineComponent
  >>

  export default Component
}

It seems to be working for importing / exporting Vue files from other Vue files, typescript files, as well as the tests. It allows mounting options like slots too, so I can do things like:

const wrapper = mount(Example, {
    props: { msg: "hello world!" },
    shallow: true,
    slots: {
      default: defineComponent({
        render() {
          return h("div", {}, "Hello world!")
        },
      }),
    },
  })

Whether or not this is the preferred or technically correct way is something to be discussed, but for now it works for me 😄 I'll keep my eyes on that thread you linked to - thanks for the heads up!

@cexbrayat
Copy link
Member

@onx2 Out of curiosity, could you try with what we settled for in the Vue CLI?

declare module '*.vue' {
  import type { DefineComponent } from 'vue';
  const component: DefineComponent;
  export default component;
}

It works pretty well in our Vue 3 projects.

@onx2
Copy link
Author

onx2 commented Oct 8, 2020

Yup, that also works for me!

@lmiller1990
Copy link
Member

It's live, 5.0.0-alpha.5.

@ghost
Copy link

ghost commented Nov 20, 2020

<script setup> probably won't stay in the current state (it's experimental), vuejs/rfcs#227

@lmiller1990
Copy link
Member

I will update vue-jest as needed! Ping me if you find any problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants