HerringtonDarkholme / av-ts

A modern, type-safe, idiomatic Vue binding library
MIT License
216 stars 11 forks source link

how to write mapState function in vuex?? #76

Open hamidh2 opened 6 years ago

hamidh2 commented 6 years ago

Hey im using typescript syntax in my vuejs project that integrated with vuex i wana use mapState method as computed in my .ts file but i got syntax error currently i am using your suggested syntax for computed function,i mean

  get counter(){
    return  this.$store.state.count;
   }

if you read the vuex docs you will know using this way is so repetitive and so boring instead using mapState is very easy and useful in large application so i wana use mapState in Typescript component and i dont know the true way. i tried below way to use mapState function it was wrong and didnt work :) :)

    get mapState({
             counter:count
          })
    or
      get mapState(['name', 'age', 'job'])

I'll be grateful if you help me.

HerringtonDarkholme commented 6 years ago

One solution is to extend a class created dynamically.


class Comp extends MapVuex({ getters: ['total'], state: ['count']}) {

}

declare MapVuex(...): { new(): {  /* some dynamic properties */ }}

You need some TypeScript-fu to implement MapVuex's type signature.

whitetrefoil commented 5 years ago

this seems to work:

@Component({
  name      : 'hello',
  computed  : {
    ...mapState({
      count: 'count',
    }),
  },
})
export default class HelloComponent extends Vue {

  count!: number

  get countDisplay(): string {
    return this.count.toString() + '!!!'
  }
}
themeler commented 4 years ago

I'm using default object component declaration, and found solution to mapping state inside components with Typescript advanced type. Should also work with above notation:

First - you create state interface to use in vuex state declaration, like:

export interface IStateRoot {
    somethings?: string[]
}

Next (one time operation) - create generic state mapper (I think best is to do it in global.d.ts so you wouldn' need to import it everywhere):

type MapStateToComputed<S> = {
    [K in keyof S]: () => S[K]
}

And finally - use mapper to reuse vuex state declaration with map state in component:

computed: {
    ...(mapState(['somethings']) as MapStateToComputed<IStateRoot>),
}

When you'll use this.somethings in component, you'll get full typescript check. Hope it helps someone.