vuejs / vue-class-component

ES / TypeScript decorator for class-style Vue components.
MIT License
5.8k stars 429 forks source link

Does not work with Vue 2.5.18 #294

Closed screendriver closed 5 years ago

screendriver commented 5 years ago

Just create a new project with Vue CLI and you get a

35:1 Unable to resolve signature of class decorator when called as an expression.
  Type '<VC extends VueClass<Vue>>(target: VC) => VC' is missing the following properties from type 'typeof HelloWorld': exte
nd, nextTick, set, delete, and 7 more.
    33 | import { Component, Prop, Vue } from 'vue-property-decorator';
    34 |
  > 35 | @Component
       | ^
    36 | export default class HelloWorld extends Vue {
    37 |   @Prop() private msg!: string;
    38 | }

This happens since the update of Vue and vue-template-compiler to version 2.5.18. With 2.5.17 everything works.

jarrodldavis commented 5 years ago

After some digging, I've found that this appears to be caused by https://github.com/vuejs/vue/pull/8595. I'm not sure exactly what's going on, but having a class method (defined in VueConstructor) that returns this seems to cause issues with the type definitions by the time they get to @Component.

Changing this to VueConstructor<Vue> appears to fix this issue and preserve the method chaining added by that pull request:

diff --git a/types/vue.d.ts b/types/vue.d.ts
index 349c3432..144fa869 100644
--- a/types/vue.d.ts
+++ b/types/vue.d.ts
@@ -111,9 +111,9 @@ export interface VueConstructor<V extends Vue = Vue> {
   component<Props>(id: string, definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;
   component(id: string, definition?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;

-  use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): this;
-  use(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): this;
-  mixin(mixin: VueConstructor | ComponentOptions<Vue>): this;
+  use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): VueConstructor<Vue>;
+  use(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): VueConstructor<Vue>;
+  mixin(mixin: VueConstructor | ComponentOptions<Vue>): VueConstructor<Vue>;
   compile(template: string): {
     render(createElement: typeof Vue.prototype.$createElement): VNode;
     staticRenderFns: (() => VNode)[];
HerringtonDarkholme commented 5 years ago

This is probably caused by variance check. I can give it a look.

ktsn commented 5 years ago

The cause is this commit which sets return type of class methods of Vue to itself. But it might be a TypeScript bug. I already filed about that in TypeScript repo. https://github.com/Microsoft/TypeScript/issues/28930

nemethmik commented 5 years ago

I have just received exactly the same error: ERROR in C:/Users/nemet/tiva11/tiva11forvue/src/components/HelloWorld.vue 36:1 Unable to resolve signature of class decorator when called as an expression. Type '<VC extends VueClass>(target: VC) => VC' is missing the following properties from type 'typeof HelloWorld': extend, nextTick, set, delete, and 7 more.

Is there a workaround? Thanks.

ZechariahMcPherson commented 5 years ago

I am having the same issue. I spent the better part of three hours working on this. There is a work around go to tsconfig.json inside "compilerOptions" : {...} insert "strictFunctionTypes":false but it is kinda dangerous work around so be careful.

nemethmik commented 5 years ago

I've just found another workaround: When creating my project with CLI 3 I set NO to the question "Use class-style component syntax?", so the problem is definitely with those nifty decorators :-)

2-5 commented 5 years ago

The change which introduced this breakage mentioned that all tests passed.

Maybe some test cases which use Vue, decorators and TypeScript together should be added, since a lot of people use them?

chs97 commented 5 years ago

Type 'VueClass' is not assignable to type 'typeof App'. Types of parameters 'options' and 'options' are incompatible. Type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>> | undefined' is not assignable to type 'ThisTypedComponentOptionsWithArrayProps<Vue, any, any, any, any> | undefined'. Type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>' is not assignable to type 'ThisTypedComponentOptionsWithArrayProps<Vue, any, any, any, any>'. Type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>' is not assignable to type 'ComponentOptions<Vue, any, any, any, any[], Record<any, any>>'.

@HerringtonDarkholme @ktsn vue@2.5.19 ~~~ vue break change.

nemethmik commented 5 years ago

I really appreciate your work, Friends. We've recently moved from another well-known JS framework over to Vue/Vuetify because CLI3 supports directly TypeScript as first class citizen. In our organization management would never allow to start a project with a programming language without a strong, well-supported type system. The other framework-chain we evaluated first had a powerful type system, but it wasn't integrated, and it was terribly slow; this was enough reason we started looking for a better solution, so we found Vue/TS/CLI3/Vuetify. The technical evaluators have to give a presentation that Vue/Vuetify with its out-of-the box support for TS (and a number of other goodies, like PWA), which came with CLI3, would be perfect for the requirements of our mobile/web business application project. When we saw how simple was to add Vuetify to a TS (sic!) project with "vue add Vuetify", all the IT management wowed.

wompeter commented 5 years ago

Just got hit by this. Did an update and project failed to compile anymore. Vue bootstrapping uses the new @Component/@Prop decorator syntax for the example templates and this breaks any project using it.

15:1 Unable to resolve signature of class decorator when called as an expression.
  Type '<VC extends VueClass<Vue>>(target: VC) => VC' is missing the following properties from type 'typeof HelloWorld': extend, nextTick, set, delete, and 7 more.
    13 | import { Component, Prop, Vue } from 'vue-property-decorator'
    14 |
  > 15 | @Component
       | ^
    16 | export default class HelloWorld extends Vue {
    17 |   @Prop() private msg!: string;
    18 | }
ktsn commented 5 years ago

We already figured out the cause and a patch is already created https://github.com/vuejs/vue/pull/9173 Please wait until the next patch version of Vue is released, use Vue <= 2.5.17 or configure "strictFunctionTypes": false.

blieque commented 5 years ago

I seem to be getting this issue, but I'm not using the class component pattern. Is it likely to be related? I've tried pulling back vue and vue-template-compiler to 2.5.17, but I'm still getting this:

TS2322: Type 'VueConstructor<{ message: string; } & Vue>' is not assignable to type 'VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<string, any>> | AsyncComponent<any, any, any, any>'.

message is a prop of my component. The component is being included from another package, and both packages are in a Lerna monorepo. Components in the same directory work OK. I have a sfc.d.ts covering the webpack alias the component is imported under. This definition does have an effect, as the error message changes if the definition is removed and the component is imported but not used (if it is used the message is the same). By "used" I mean referenced in App.vue's components{}.

I've no doubt this is the wrong place for this, but I'm at a bit of a loss. Sorry!

Edit: After looking again, this seems to be a separate error. Is there a better place to post this?

tvkit commented 4 years ago

Just sharing a related issue that may help others...

I inadvertently hijacked the component's dataproperty having it typed as an array; e.g.,

private data: EventRow[] = [];

This caused the following error:

Property 'data' in type 'MyComponent' is not assignable to the same property in base type 'object & Record<never, any> & Vue'.

which in turn triggered the error mentioned by the OP:

Unable to resolve signature of class decorator when called as an expression.

ktsn commented 4 years ago

@tvkit Your issue is not related with this issue and already fixed in v7.2.1

hisuwh commented 4 years ago

I've just had this issue. I tried updating vue but no avail. Tried setting strictFunctionTypes: false but that didn't help either:

Unable to resolve signature of class decorator when called as an expression.
  Type '<VC extends VueClass<Vue>>(target: VC) => VC' is missing the following properties from type 'typeof SaveUpdateMixin': extend, nextTick, set, delete, and 7 more.ts(1238)

vue@2.6.12 vue-class-component@7.2.5

Manubi commented 3 years ago

same problem here... just updated to vue@2.6.12 and vue-class-component@7.2.6 was working with vue@2.6.11 and vue-class-component@7.2.3

npm_run_serve_and_WhatsApp
burloiumarian23 commented 3 years ago

Looks like this issue is reproducible also in latest Vue 2.6.12 ... it breaks everything after updating dependencies with npm update ... what is the workaround ? i have been searching a solution for days...

bodograumann commented 3 years ago

@ktsn Maybe this issue should be locked, because people are still coming here with similar problems, but not finding any help.

For anybody having “this” problem.

Please first of all reproduce it in a minimal example. Often you will then already see what the cause is. Otherwise try to ask for help on the discord server and provide the example.

If you are then confident that you found a problem with this package, still do not post here in this threat. Instead open a new issue and describe the problem there, again showing your minimal example. You can of course reference this issue in the new one.

Furthermore, to make sure people can help you, the best approach is to share your example in a repository that anybody can just check out and directly see the error occurring for themselves, as well as starting to trace it.

burloiumarian23 commented 3 years ago

After npm install it gives me the latest Vue , version 2.6.12. Also i have node js bigger than 12.16.1 ... any ideas ? If rolled back to node js 12.16.1 or smaller than it , it does not generate this issue :

Type 'VueClass' is not assignable to type 'typeof App'. Types of parameters 'options' and 'options' are incompatible. Type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>> | undefined' is not assignable to type 'ThisTypedComponentOptionsWithArrayProps<Vue, any, any, any, any> | undefined'. Type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>' is not assignable to type 'ThisTypedComponentOptionsWithArrayProps<Vue, any, any, any, any>'. Type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>' is not assignable to type 'ComponentOptions<Vue, any, any, any, any[], Record<any, any>>'.

Here is my package json . what else should be helpful ? { "name": "my project", "version": "1.0.0", "private": true, "description": "The UI platform", "author": "UI Team", "scripts": { "build": "cross-env NODE_ENV=production vue-cli-service build --mode=production", "start": "cd ./dist && npm install && node index.js", "lint": "vue-cli-service lint", "build:report": "cross-env vue-cli-service build --report", "dev": "cross-env NODE_ENV=dev& nodemon --exec vue-cli-service serve --open", "dev-debug": "nodemon --exec cross-env VUE_APP_DEBUG=true vue-cli-service serve --open", "docker": "cross-env NODE_ENV=docker vue-cli-service serve --mode=production",
"e2e": "node test/e2e/runner.js", "lint-fix": "vue-cli-service lint --fix", "test-env": "SET NODE_ENV=testing& nodemon --exec vue-cli-service serve --open", "unit": "SET NODE_ENV=test & jest --no-cache --coverage --config jest.config.js --watchAll", "watch": "webpack --config ./node_modules/@vue/cli-service/webpack.config.js --watch" }, "dependencies": { "apollo-cache-inmemory": "^1.6.6", "apollo-client": "^2.6.10", "apollo-link-context": "^1.0.20", "apollo-link-http": "^1.5.17", "axios": "^0.19.2", "axios-request-handler": "^1.0.4", "base64-img": "^1.0.4", "camelcase": "^5.3.1", "chart.js": "^2.9.4", "chartist": "^0.11.2", "chartist-plugin-tooltips": "0.0.17", "core-js": "^3.6.5", "font-awesome": "^4.7.0", "graphql": "^14.7.0", "graphql-tag": "^2.11.0", "inversify-props": "^2.2.6", "ionicons": "^4.6.1", "ip-range-check": "^0.2.0", "isomorphic-fetch": "^2.2.1", "jquery": "^3.5.1", "jquery-ui": "^1.12.1", "lodash": "^4.17.20", "materialize-css": "^1.0.0", "nanobar": "^0.4.2", "password-validator": "^5.1.0", "perfect-scrollbar": "^1.5.0", "popper.js": "^1.16.1", "raphael": "^2.2.8", "reflect-metadata": "^0.1.13", "sass-mq": "^5.0.0", "sockjs-client": "^1.5.0", "underscore": "^1.11.0", "underscore.get": "^0.2.9", "v-debounce": "^0.1.2", "vis": "^4.21.0-EOL", "vue": "^2.6.11", "vue-async-computed": "^3.9.0", "vue-avatar": "^2.3.1", "vue-axios": "^2.1.5", "vue-class-component": "^7.2.3", "vue-clickaway": "^2.1.0", "vue-color": "^2.7.1", "vue-contenteditable": "^1.0.2", "vue-disable-autocomplete": "0.0.4", "vue-form-wizard": "^0.8.4", "vue-lodash": "^2.1.2", "vue-native-websocket": "^2.0.14", "vue-notifyjs": "^0.3.0", "vue-property-decorator": "8.5.1", "vue-router": "^3.4.7", "vue-slider-component": "^2.8.16", "vue2-daterangepicker-component": "^2.0.3", "vue2-transitions": "^0.2.3", "vuedraggable": "^2.24.3", "vuelidate": "^0.7.6", "vuex": "^3.5.1", "vuex-class": "^0.3.2", "vuex-module-decorators": "^0.11.0", "webstomp-client": "^1.2.6" }, "devDependencies": { "@babel/core": "^7.12.3", "@babel/preset-env": "^7.12.1", "@types/autoprefixer": "^9.7.2", "@types/babel-core": "6.25.6", "@types/babel__core": "^7.1.10", "@types/chart.js": "^2.9.27", "@types/chartist": "^0.9.48", "@types/eslint": "^6.8.1", "@types/eslint-plugin-prettier": "^2.2.0", "@types/gulp": "^4.0.7", "@types/gulp-zip": "^4.0.1", "@types/isomorphic-fetch": "^0.0.35", "@types/jest": "^25.2.3", "@types/jquery": "^3.5.3", "@types/materialize-css": "^1.0.8", "@types/node-sass": "^4.11.1", "@types/prettier": "^1.19.1", "@types/raphael": "^2.3.0", "@types/underscore": "^1.10.24", "@types/vue-clickaway": "^2.2.0", "@types/vue-color": "^2.4.3", "@types/webpack": "^4.41.23", "@typescript-eslint/eslint-plugin": "^2.34.0", "@typescript-eslint/parser": "^2.34.0", "@vue/babel-preset-app": "^4.5.8", "@vue/cli-plugin-babel": "^3.9.0", "@vue/cli-plugin-eslint": "^3.12.1", "@vue/cli-plugin-typescript": "^4.5.8", "@vue/cli-service": "^4.5.8", "@vue/eslint-config-prettier": "^3.0.5", "@vue/eslint-config-typescript": "^5.1.0", "@vue/test-utils": "^1.1.0", "autoprefixer": "^9.8.6", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^8.2.6", "babel-jest": "^24.9.0", "babel-loader": "^8.1.0", "babel-plugin-lodash": "^3.3.4", "cross-env": "^5.2.0", "custom-env": "^1.0.2", "empty-module": "0.0.2", "eslint": "^6.8.0", "eslint-config-prettier": "^6.14.0", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-vue": "^6.2.2", "flush-promises": "^1.0.2", "gulp": "^4.0.2", "gulp-zip": "^4.2.0", "husky": "^4.3.0", "jest": "^24.9.0", "jest-canvas-mock": "^2.3.0", "jest-mock-axios": "^3.2.0", "jest-serializer-vue": "^2.0.2", "lint-staged": "^10.4.2", "node-sass": "^4.14.1", "nodemon": "^1.19.4", "prettier": "^1.19.1", "pretty-quick": "^2.0.2", "regenerator-runtime": "^0.12.1", "sass-loader": "^6.0.7", "ts-jest": "^25.5.1", "typescript": "^3.9.7", "url-loader": "^1.1.2", "vue-eslint-parser": "^6.0.5", "vue-jest": "^2.6.0", "vue-loader": "^15.9.3", "vue-template-compiler": "^2.6.11", "webpack": "^4.44.2", "webpack-cli": "^3.3.12", "webpack-livereload-plugin": "^2.3.0", "webpackbar": "^4.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 11" ], "jest": { "moduleFileExtensions": [ "js", "json", "vue" ], "transform": { "^.+\.js$": "babel-jest", ".\.(vue)$": "vue-jest" }, "moduleNameMapper": { "^@/(.)$": "/$1" }, "snapshotSerializers": [ "jest-serializer-vue" ], "moduleDirectories": [ "node_modules", "src" ], "transformIgnorePatterns": [ "node_modules/(?!(babel-jest|jest-vue-preprocessor)/)" ] }, "config": { "maxPackagesNumber": 100, "maxSizeBites": 840400, "allowedLicenseTypes": [ "permissive", "publicDomain", "protective", "uncategorized" ] }, "engines": { "node": ">= 10.x.x", "npm": ">= 6.x.x" }, "husky": { "hooks": { "pre-commit": "pretty-quick --staged" } } }