Skip to content

Better types for wrapper.vm when the component is closed #972

Open
@cexbrayat

Description

@cexbrayat

Since 2.0.0-rc.15, we are now exposing $.proxy as wrapper.vm to simplify testing of script setup component,
allowing to test the following component:

<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>

with expect(wrapper.vm.count).toBe(0), even if count is not exposed by the component (see PR #931 ).

This works, but for TS (vue-tsc), wrapper.vm does not have a count property, because wrapper.vm is typed as ComponentPublicInstance.

Ideally, we would like wrapper.vm type to reflect that it is actually not the component public instance, but the properties exposed to the template. Is there a way to infer that?

To reproduce, remove "exclude": ["tests/expose.spec.ts"] from tsconfig.volar.json, and run yarn vue-tsc. It fails with:

tests/expose.spec.ts:38:23 - error TS2339: Property 'count' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<Readonly<{} & {} & {}> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>; ... 10 more ...; $watch(source: string | Function, cb: Function, options?: WatchOptions<...> | undefined): WatchStopHandle; } & ... 4 more ... & ComponentC...'.

38     expect(wrapper.vm.count).toBe(1)

For readers interested in this issue, you can workaround it with an explicit cast:
expect((wrapper.vm as unknown as { count: number }).count).toBe(1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions