vuejs / test-utils

Vue Test Utils for Vue 3
https://test-utils.vuejs.org
MIT License
1.03k stars 245 forks source link

Bug: TypeScript error when checking wrapper.props().myProperty #2478

Closed MikeEtlingerRM closed 2 months ago

MikeEtlingerRM commented 2 months ago

Describe the bug

Hello test-utils team!

I am in the process of upgrading to @vue/test-utils@v2.4.6 from a very old v2.0.0rc version. I was able to upgrade to v2.3 at the highest before getting a typescript error when checking the values of props in my spec files.

Here's my component/test:

<template>
  <h1>I'm a cool {{ msg }}</h1>
</template>

<script setup lang="ts">
interface Props {
  message: string;
}

defineProps<Props>();
</script>
import { shallowMount } from "@vue/test-utils";

import CoolMessage from "./CoolMessage.vue";

describe("CoolMessage", function () {
  const mountWrapper = (props = { message: "cool" }) => {
    vi.resetAllMocks();
    return shallowMount(CoolMessage, { props });
  };

  test("should pass typecheck", async () => {
    const wrapper = mountWrapper();
    expect(wrapper.props().message).toBeTruthy();
  });
});

Here's the error I'm seeing when I run tsc --noEmit --skipLibCheck:

components/CoolMessage.spec.ts:13:28 - error TS2339: Property 'message' does not exist on type '{}'.

13     expect(wrapper.props().message).toBeTruthy();
                              ~~~~~~~
Found 1 error in components/CoolMessage.spec.ts:13

Can you help me debug this? I can't tell if this is user error or if I'm running into a bug here.

Thank you for any help or insight on this 🙏

To Reproduce

https://github.com/ripple-recruiting/vue-test-utils-bug

Expected behavior

I'd expect the behavior from previous versions of test-utils. wrapper.props().myProperty is properly typed, with no ts errors.

Related information:

System: OS: macOS 14.5 CPU: (12) arm64 Apple M3 Pro Memory: 93.89 MB / 18.00 GB Shell: 5.9 - /bin/zsh npmPackages: @vue/test-utils: ^2.4.6 => 2.4.6 vitest: ^1.5.3 => 1.6.0 vue: ^3.4.26 => 3.4.26

Additional context

cexbrayat commented 2 months ago

Hi @MikeEtlingerRM

If you want proper typechecking in a Vue project, you should use vue-tsc from https://github.com/vuejs/language-tools instead of tsc. If you use this, you'll have no compilation error in your test. tsc isn't able to pick up the defined props on its own.

You can try online using https://stackblitz.com/github/vuejs/create-vue-templates/tree/main/typescript-vitest?file=src%2Fcomponents%2F__tests__%2FHelloWorld.spec.ts or by creating a project with https://github.com/vuejs/create-vue to see the proper setup.

In your repro, simply adding "vue-tsc": "latest" as a dev dependency and running vue-tsc --noEmit instead of tsc fixes the typechecking.

MikeEtlingerRM commented 2 months ago

Wow thank you so much for your help!

I’m curious though, can you explain what changed between v2.3 and v2.4?

Is it that the test file wasn’t type checked correctly in 2.3 at all?

because in 2.3 I was able to see that wrapper.props().message is of type string and it passed type checking.

It seems semi unintuitive to run vue-tsc on .ts files but in my main project I do have vue-tsc but I needed to strip everything out for the min repro.

Thanks again!