cklmercer / vue-stash

Easily share reactive data between your Vue components.
MIT License
403 stars 29 forks source link

TypeScript support #15

Closed ozeebee closed 7 years ago

ozeebee commented 7 years ago

Is there any way to use this plugin in TypeScript class component ?

import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  name: 'MyComponent'
})
export default class MyComponent extends Vue {
  message = 'Hello from MyComponent'
}

Any idea ? thanks

cklmercer commented 7 years ago

Sorry about the delayed reply.. for some reason I haven't been getting notifications for my personal repos :(

I've never used typescript myself, so I'm not sure how to go about implementing support for it. A PR would however be welcomed!

ozeebee commented 7 years ago

Hi, I'm also new to typescript hence this question ;) Anyway, in the meantime, I have come up with the following solution:

First, in order to add a store option to the @Component decorator, we have to add the store to Vue's ComponentOptions. We also have to declare the $store property in the Vue class so we can use it without compilation error. I do this by creating a new declaration file:

vue-stash.d.ts

/**
 * Declarations to add vue-stash's 'store' property in @Component options
 */
declare module "vue-stash" {
  import Vue from 'vue'

  /**
   * @module augmentation to ComponentOptions defined by Vuejs
   */
  module "vue/types/options" {
    interface ComponentOptions<V extends Vue> {
      store?: any[] | {}
    }
  }

  module "vue/types/vue" {
    interface Vue {
      $store: any
    }
  }  
}

We can now use it like this:

//...
import { StoreType } from '../models'

@Component({
  props: {
    propMessage: String
  },
  store: ['user']
})
export default class UserAdmin extends Vue {
  // declare our typed store (only needed when using $store in code)
  $store: StoreType

  test () {
    console.debug('[DEBUG] test()')
    this.$store.user.name = 'TOTO'
  }
}
//...

Voilà. I don't know if this is the best way to use it with vue-class-component but it's rather simple and works quite well for my needs. I guess one could also create a custom decorator but I leave this as an exercise for people interested in such a technique.

cklmercer commented 7 years ago

glad you figured this out! Sorry I couldn't be any help with it!