Vue JS - custom properties on vue component gives TS errors

Viewed 449

I have created some Vue middleware and I am trying to add a custom property to one of my components in Vue like so:

middleware.js:

import { VueConstructor } from 'vue/types';
function eventPlugin(vue: VueConstructor): void {
  const Socket = new someClass();

  Object.defineProperties(vue.prototype, {
    $socket: {
      get: function get() {
        return Socket;
      },
    },
  });
  vue.$socket = Socket;
}

myComponent.js

const MyComponent = Vue.extend({
  name: 'MyComponent',
  $socket: {
    event(data: any) {

    }
  },
  methods: {
    MyMethod() {

    }
  }
})

app.js

import Vue from 'vue';
import eventPlugin from './middleware.js';
import MyComponent from './myComponent.js'
Vue.use(eventPlugin);

export default new Vue({
  render: (h) => h(MyComponent),
}).$mount('#app');

The custom property I am trying to add here is obviously socket. The problem is when I add it I get typescript errors:

Object literal may only specify known properties, and 'socket' does not exist in type 'ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>'.

As you can see in middleware.js I have tried defining the property there so I am not sure why I am receiving the error?

1 Answers

When adding instance properties or component options, you also need to augment the existing type declarations.

Based on Augmenting Types for Use with Plugins (Vue 2):

  • To type-hint the $socket instance property:

    declare module 'vue/types/vue' {
      interface VueConstructor {
        $socket: string
      }
    }
    
    export {}
    
  • To type-hint the $socket component option:

    import Vue from 'vue'
    
    declare module 'vue/types/options' {
      interface ComponentOptions<V extends Vue> {
        $socket?: string
      }
    }
    
    export {}
    

The type declarations above should go in a .d.ts file in your src directory. If using VS Code, any new .d.ts files might require restarting VS Code to load.

Related