Search code examples
typescriptvue.jsvuejs2konvavue-konva

Unknown VueKonva Type w/ TypeScript


I recently configured TypeScript for my Vue 2 project. Everything is working except for my VueKonva plugin - I receive the error below on app launch.

I tried adding "vue-konva", to types in tsconfig.json but no luck. Creating a vue-konva.d.js file also didn't help. Can anyone help me understand what I'm doing wrong?

Failed to compile.

src/main.ts:8:3
TS2769: No overload matches this call.
  Overload 1 of 3, '(options?: ThisTypedComponentOptionsWithArrayProps<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 6 more ..., ComponentOptionsMixin> | undefined): CombinedVueInstance<...>', gave the following error.
    Argument of type '{ VueKonva: PluginObject<{}> | PluginFunction<{}>; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithArrayProps<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 6 more ..., ComponentOptionsMixin>'.
      Object literal may only specify known properties, and 'VueKonva' does not exist in type 'ThisTypedComponentOptionsWithArrayProps<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 6 more ..., ComponentOptionsMixin>'.
  Overload 2 of 3, '(options?: ThisTypedComponentOptionsWithRecordProps<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 6 more ..., ComponentOptionsMixin> | undefined): CombinedVueInstance<...>', gave the following error.
    Argument of type '{ VueKonva: PluginObject<{}> | PluginFunction<{}>; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithRecordProps<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 6 more ..., ComponentOptionsMixin>'.
      Object literal may only specify known properties, and 'VueKonva' does not exist in type 'ThisTypedComponentOptionsWithRecordProps<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 6 more ..., ComponentOptionsMixin>'.
  Overload 3 of 3, '(options?: ComponentOptions<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 7 more ..., ComponentOptionsMixin> | undefined): CombinedVueInstance<...>', gave the following error.
    Argument of type '{ VueKonva: PluginObject<{}> | PluginFunction<{}>; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ComponentOptions<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 7 more ..., ComponentOptionsMixin>'.
      Object literal may only specify known properties, and 'VueKonva' does not exist in type 'ComponentOptions<Vue<Record<string, any>, Record<string, any>, never, never, (event: string, ...args: any[]) => Vue<Record<string, any>, Record<string, any>, never, never, ...>>, ... 7 more ..., ComponentOptionsMixin>'.
     6 |
     7 | new Vue({
  >  8 |   VueKonva,
       |   ^^^^^^^^
     9 |   render: h => h(App)
    10 | }).$mount("#app");
    11 |

main.ts

import Vue from "vue";
import App from "@/App.vue";
import VueKonva from 'vue-konva';

Vue.use(VueKonva);

new Vue({
  VueKonva,
  render: h => h(App)
}).$mount("#app");

tsconfig.js

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "noImplicitAny": false,
    "allowJs": true,
    "baseUrl": ".",
    "types": [
      "vue-konva",
      "vuetify",
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

Solution

  • The error message points correctly at your problem.

      >  8 |   VueKonva,
           |   ^^^^^^^^
    

    Check the project documentation on how to use VueKonva.

    import { createApp } from 'vue';
    import App from './App.vue';
    import VueKonva from 'vue-konva';
    
    const app = createApp(App);
    app.use(VueKonva);
    app.mount('#app');
    

    Here is the working example for Vue v3

    const { createApp } = Vue 
    
    const app = createApp({
    data() {
      return {
        configKonva: {
          width: 200,
          height: 200,
        },
        configCircle: {
          x: 100,
          y: 100,
          radius: 70,
          fill: 'red',
          stroke: 'black',
          strokeWidth: 4,
        }
      }
    }});
    app.use(VueKonva);
    app.mount('#app');
    <div id="app">
      <v-stage ref="stage" :config="configKonva">
        <v-layer ref="layer">
          <v-circle :config="configCircle"></v-circle>
        </v-layer>
      </v-stage>
    </div>
    <!--1. Link Vue Javascript & Konva-->
    <script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
    <script src="https://unpkg.com/[email protected]/konva.min.js"></script>
    <!--2. Link VueKonva Javascript -->
    <script src="https://unpkg.com/[email protected]/umd/vue-konva.js"></script>

    UPDATE

    1. Vue v2 has no $mount method.
    2. Do not put the plugin inside the App definition

    Your code

    new Vue({
      // this is not necessary -> VueKonva,
      render: h => h(App)
    }) // this is not necessary -> .$mount("#app");
    

    Here is the working example for Vue v2

    Vue.use(VueKonva)
    
    new Vue({
      el: '#app',
      data() {
        return {
          configKonva: {
            width: 200,
            height: 200,
          },
          configCircle: {
            x: 100,
            y: 100,
            radius: 70,
            fill: 'red',
            stroke: 'black',
            strokeWidth: 4,
          }
        }
      }
    })
    <div id="app">
      <v-stage ref="stage" :config="configKonva">
        <v-layer ref="layer">
          <v-circle :config="configCircle"></v-circle>
        </v-layer>
      </v-stage>
    </div>
    <!--1. Link Vue Javascript & Konva-->
    <script src="https://unpkg.com/[email protected]/konva.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
    <!--2. Link VueKonva Javascript -->
    <script src="https://unpkg.com/[email protected]/umd/vue-konva.js"></script>