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

Typescript interface error RouterLink.d.ts #143

Closed
shaneostonstowe opened this issue Jun 23, 2020 · 24 comments
Closed

Typescript interface error RouterLink.d.ts #143

shaneostonstowe opened this issue Jun 23, 2020 · 24 comments

Comments

@shaneostonstowe
Copy link

shaneostonstowe commented Jun 23, 2020

I have installed a VueJS 3 app and upgraded test-utils to the latest alpha. An attempt to serve the app locally returns this error:

node_modules/@vue/test-utils/dist/components/RouterLinkStub.d.ts:5:12 - error TS2707: Generic type 'ComponentOptionsBase<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>' requires between 8 and 9 type arguments.

5 } & {}>) & import("vue").ComponentOptionsBase<Readonly<{
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6     to: any;
  ~~~~~~~~~~~~
7 } & {}>, unknown, unknown, {}, {}, Record<string, any>, string> & {
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It seems the interface ComponentOptionsBase is incorrectly specified or RouterLink.d.ts has the wrong number of arguments.

Is this expected behaviour or is this an issue? Is there a workaround?

@rtbo
Copy link

rtbo commented Jun 24, 2020

This has to do with vue-test-utils-next relying on vue-3.0.0-beta.12 and your app likely on vue-3.0.0-beta.15.

I have the same issue. I tried downgrading vue to beta.12, but I now have other typing issues.

I'm ending up testing vue3 without type checks

@lmiller1990
Copy link
Member

That (may) fix it. I will try repro tonight and see if it does.

I will do a release for the latest Vue 3 beta in the next day or two! We just merged up something that was blocking this.

@lmiller1990
Copy link
Member

Alpha 7 is out now: https://github.com/vuejs/vue-test-utils-next/releases/tag/2.0.0-alpha.7

Can you see if this resolves your issue?

@lmiller1990
Copy link
Member

@rtbo can you give this another try?

@rtbo
Copy link

rtbo commented Jul 1, 2020

Same problem with vue-test-utils-next-2.0.0-alpha.8.

Repro:

git clone git@github.com:rtbo/testvue3-ts
cd testvue3-ts
yarn install
yarn test:unit

 ERROR  Failed to compile with 2 errors

 error  in /home/remi/dev/test/testvue3-ts/node_modules/@vue/test-utils/dist/components/RouterLinkStub.d.ts

ERROR in /home/remi/dev/test/testvue3-ts/node_modules/@vue/test-utils/dist/components/RouterLinkStub.d.ts(5,12):
5:12 Generic type 'ComponentOptionsBase<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>' requires between 8 and 9 type arguments.
    3 | } & {}, unknown, unknown, {}, {}, Record<string, any>, import("vue").VNodeProps & {
    4 |     to: any;
  > 5 | } & {}>) & import("vue").ComponentOptionsBase<Readonly<{
      |            ^
    6 |     to: any;
    7 | } & {}>, unknown, unknown, {}, {}, Record<string, any>, string> & {
    8 |     props: {

 error  in /home/remi/dev/test/testvue3-ts/tests/unit/example.spec.ts

ERROR in /home/remi/dev/test/testvue3-ts/tests/unit/example.spec.ts(8,34):
8:34 No overload matches this call.
  The last overload gave the following error.
    Argument of type '{}' is not assignable to parameter of type 'ComponentOptionsWithObjectProps<readonly string[] | Readonly<ComponentObjectPropsOptions<Data>>, unknown, unknown, {}, {}, Record<string, any>, ComponentOptionsMixin, ComponentOptionsMixin, string, Readonly<...> | Readonly<...>>'.
      Property 'props' is missing in type '{}' but required in type '{ props: readonly string[] | Readonly<ComponentObjectPropsOptions<Data>>; }'.
     6 |   it("renders props.msg when passed", () => {
     7 |     const msg = "new message";
  >  8 |     const wrapper = shallowMount(HelloWorld, {
       |                                  ^
     9 |       props: { msg }
    10 |     });
    11 |     expect(wrapper.text()).to.include(msg);

@lmiller1990
Copy link
Member

lmiller1990 commented Jul 1, 2020

Can you share your test? Code-base? Are you only the latest beta for Vue? I am on beta 16 and alpha 8 for Vue and VTU respectively.

There is a template you could use here to repro: https://github.com/lmiller1990/vtu-next-demo.

I can' see where you are using RouterLink here. Or this just happens as soon as you run test:unit?

@rtbo
Copy link

rtbo commented Jul 2, 2020

@lmiller1990 the repo URL is in my previous message. Here again https://github.com/rtbo/testvue3-ts

I've started a template with vue-cli that includes vue-router and unit tests. I then activated vue-next with vue add vue-next.
I think that's pretty much my testing code base (apart may be one or 2 tweaks).

@rtbo
Copy link

rtbo commented Jul 2, 2020

With https://github.com/lmiller1990/vtu-next-demo I don't have compilation error.

@lmiller1990
Copy link
Member

lmiller1990 commented Jul 2, 2020

Weird one. One obvious problem is you are doing export default Vue.extend in your HelloWorld.vue file, but even changing that did nothing.

I'll keep playing around. I guess it is some conflicting type definitions somewhere...

@BlakeTheAwesome
Copy link

Just adding a data point:
I'm getting this in my repo when I npm run my build, serve or test:e2e scripts.
My package.json looks like:

{
  "name": "vue3-starter",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@types/chart.js": "^2.9.21",
    "chart.js": "^2.9.3",
    "core-js": "^3.6.4",
    "vue": "^3.0.0-beta.17",
    "vue-router": "^4.0.0-alpha.14"
  },
  "devDependencies": {
    "@babel/node": "^7.8.7",
    "@babel/preset-env": "^7.9.0",
    "@cypress/webpack-preprocessor": "^5.4.1",
    "@types/jest": "^25.2.1",
    "@typescript-eslint/eslint-plugin": "^2.34.0",
    "@typescript-eslint/parser": "^2.34.0",
    "@vue/cli-plugin-babel": "~4.3.0",
    "@vue/cli-plugin-e2e-cypress": "~4.3.0",
    "@vue/cli-plugin-eslint": "~4.3.0",
    "@vue/cli-plugin-typescript": "^4.3.1",
    "@vue/cli-plugin-unit-jest": "~4.4.6",
    "@vue/cli-service": "^4.4.0",
    "@vue/compiler-sfc": "^3.0.0-beta.17",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-typescript": "^5.0.2",
    "@vue/test-utils": "^2.0.0-alpha.8",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^25.2.6",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.1.1",
    "eslint-plugin-vue": "^7.0.0-alpha.3",
    "jest": "^25.2.7",
    "prettier": "^1.19.1",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "ts-jest": "^25.3.1",
    "ts-loader": "^7.0.4",
    "typescript": "^3.8.3",
    "vue-cli-plugin-vue-next": "^0.1.3",
    "vue-cli-plugin-vuetify": "^2.0.5",
    "vue-jest": "^5.0.0-alpha.1",
    "vue-loader": "^16.0.0-alpha.3"
  }
}

@lmiller1990
Copy link
Member

lmiller1990 commented Jul 3, 2020

I am getting this in your repo too, I cannot repro in my own template. Not sure why npm run serve is even looking at a test file, though?? The mere presence of VTU next breaks something??

I wonder if we should write a cli-plugin for test-utils next and see if that helps with the dependency weirdness.

@lmiller1990
Copy link
Member

Potential stupid solution: simplify the RouterStub definitions (no real reason it needs to be strongly typed with defineComponent.

I will try this today. TS is hard sometimes!

@cexbrayat
Copy link
Member

Yes, this is basically the same root issue than #143
It's a bit annoying but we should be able to fix it eventually.

Right now you can:

  • add skipLibCheck to your tsconfig.json (fixes the first issue)
  • the second one is trickier: you need to use defineComponent in your component, and to tweak the CLI config to not use fork-ts-checker which is not reading properly the shim file:
module.exports = {
  chainWebpack: config => {
    // fork-ts-checker is sadly ignoring the Vue shim
    // and throws incorrect errors
    // we disable it as it is just a nice to have to speed up the build
    config.plugins.delete('fork-ts-checker');
    config.module
      .rule('ts')
      .use('ts-loader')
      .tap(options => {
        return { ...options, transpileOnly: false };
      });
  }
};

I haven't found the root reason why we need this, but hopefully I will.
In the meantime, if you want to have a proper minimal CLI setup with TS, you can check out the first step of my tutorial (shameless plug, I know, but you'll be able to download all the necessary config files, and be up and running in no time).

@lmiller1990 Yes, just having bad typings in VTU breaks yarn serve because the CLI is not properly configured: we just have one tsconfig which compiles all the TS file, where we should have two config (one dedicated to the project, and one dedicated to the tests). I've been meaning to change that for a while as well.

@lmiller1990
Copy link
Member

Is there something we can do on our end? Adding that transpileOnly mod is pretty hard, many people will not know/want to extend their webpack config. Ideally you should just add vue-jest, vue-test-utils and be ready to rock and roll.

We should add this to the README, perhaps. Or maybe we need a vue-test-utils-next cli plugin.

@cexbrayat
Copy link
Member

@lmiller1990 I think we should be able to fix the first issue on VTU side. For the second one, I spent some time debugging it and came with this workaround, but I was hoping to discuss it with @sodatea . This might be a good occasion to have his opinion on the matter 🙂 (cc @sodatea )

@haoqunjiang
Copy link
Member

I've also encountered this issue when working on vue-class-component integration.

Yeah, while there are type issues to fix in the test-utils, skipLibCheck is the fix for common Vue CLI projects.

we should have two config (one dedicated to the project, and one dedicated to the tests)

After a second thought, I think it may not be the best option. If we have a dedicate tsconfig for test, what about production mode? Shall we have 3 different configs or just reuse one for both test and production? Both options don't feel right to me.

Actually, after reading jaredpalmer/tsdx#529, I'm inclined to have skipLibCheck enabled for all new projects. (Should be turned off for libraries, considering facebook/create-react-app#8964, but we don't have a dedicated library template, so I guess we just need to document it somewhere)

@cexbrayat
Copy link
Member

cexbrayat commented Jul 14, 2020

skipLibCheck is indeed a common workaround, and it's usually OK to use in an app (but IIRC it also disable checking local d.ts files which was the reason it did not become the default option in Angular CLI projects for example).

Anyway, we should really fix the issue in VTU at one point.

For the separate tsconfig: you don't need a third one for production. The point of having a tsconfig.spec.json is usually to extend the app one to include the spec.ts files. That way, having a compilation error in a test file does not impact serving the app, which is really handy when developing an app. It also speeds up the compilation a lot in big projects, as TS has half the files to compile. It also allows a more fine-tuning for types (for example you only include jest or jasmine types in the tsconfig for tests, as it does not make sense fo an application). You can also decide to have slightly less strict settings in test than in the rest of the application. I really think it would be a great win for TS developers :)

@haoqunjiang
Copy link
Member

The point of having a tsconfig.spec.json is usually to extend the app one to include the spec.ts files.

Oh, that makes sense.

but IIRC it also disable checking local d.ts files which was the reason it did not become the default option in Angular CLI projects for example

🤔 Hmm, We can discuss it in a separate thread. But as far as I can tell, the community seems more inclined to not recommend skipLibCheck, esp. considering the Vue 2 TS definitions are not that perfect compared to Angular or Vue 3.

@lmiller1990
Copy link
Member

I don't understand why we need a workaround. What is the actual problem? Why does exporting a component with defineComponent cause this problem in the first place? I have used defineComponent many times and not had this problem in any of my other projects.

@haoqunjiang
Copy link
Member

@lmiller1990 The bug here is that the published version of dist/components/RouterLinkStub is still built from vue@3.0.0-beta.12. There's a breaking change related to the type definitions in beta.15 vuejs/core#626

Maybe due to the cache from rollup-plugin-typescript2 (under node_modules/.cache, need to set the clean option to true to disable it https://github.com/ezolenko/rollup-plugin-typescript2#plugin-options)

A clean build of this repo fixes this issue.

@lmiller1990
Copy link
Member

I wonder if the cache was the problem - we have definitely done a release since beta.15.

I will do another release with the latest, cleaned build in the next day or so! Thanks. I guess we should move to beta now (I don't see any blockers) after this fix is released.

@haoqunjiang
Copy link
Member

See this file: https://unpkg.com/browse/@vue/test-utils@2.0.0-alpha.8/dist/components/RouterLinkStub.d.ts

If it's correctly built from vue >= 3.0.0-beta.15, there should be something like ComponentOptionsMixin in it.

@cexbrayat
Copy link
Member

Now that @lmiller1990 released 2.0.0-beta.0, I can confirm that the workaround for skipLibCheck is no longer needed.

@lmiller1990
Copy link
Member

Great!

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

6 participants