Skip to content

How to use ...mapGetters with class components? Typescript errors #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wahidrahim opened this issue Jun 24, 2017 · 11 comments
Closed

How to use ...mapGetters with class components? Typescript errors #109

wahidrahim opened this issue Jun 24, 2017 · 11 comments

Comments

@wahidrahim
Copy link

When I use mapGetters for computed properties in a class component, I get errors such that "Property '_____' does not exist` for all computed properties using mapGetters. Not sure if this is a typescript/ts-loader issue.

screen shot 2017-06-24 at 3 36 34 pm

@ktsn
Copy link
Member

ktsn commented Jun 25, 2017

You can declare the properties in the class or use a mapper like vuex-class.

@Component({
  computed: mapGetters(['foo'])
})
class App extends Vue {
  foo: string
}

@lemmycaution
Copy link

Hi, given solution also generates error for me. Any tips most appreciated, thanks.

screen shot 2018-12-12 at 15 29 05

below are the deps from package json if it makes any sense,

...
  "dependencies": {
    "d3": "^5.7.0",
    "lodash": "^4.17.11",
    "register-service-worker": "^1.5.2",
    "vue": "^2.5.17",
    "vue-class-component": "^6.0.0",
    "vue-property-decorator": "^7.0.0",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1",
    "whatwg-fetch": "^3.0.0"
  },
  "devDependencies": {
    "@types/d3": "^5.0.1",
    "@types/jest": "^23.1.4",
    "@types/lodash": "^4.14.118",
    "@vue/cli-plugin-babel": "^3.1.1",
    "@vue/cli-plugin-pwa": "^3.1.1",
    "@vue/cli-plugin-typescript": "^3.1.1",
    "@vue/cli-plugin-unit-jest": "^3.1.1",
    "@vue/cli-service": "^3.1.1",
    "@vue/test-utils": "^1.0.0-beta.20",
    "babel-core": "7.0.0-bridge.0",
    "ts-jest": "^23.0.0",
    "typescript": "2.9.2",
    "vue-template-compiler": "^2.5.17"
  }
}

@CFourPO
Copy link

CFourPO commented Dec 13, 2018

I also have been trying to figure out a way to remove that error, but have been unsuccessful. The only way that I have been able to suppress the error is by casting this to type any. This just feels wrong and removes a lot of the benefits of using Typescript in the first place.

@Component({
  computed: {
    ...mapGetters('ChartModule', {
      charts: 'getCharts'
    })
  }
})
export default class ChartCompoment extends Vue {
   created() {
     console.log((this as any).charts)
   }
}

The other option that I have considered is using @State, @Mutation, etc. decorators in the component, but that requires one decorator for each mapped function. This looks clunky and is far less readable when you start to have many of these decorators in one component.

Conclusion:
I just want to be able to reference map[Getters/Mutations/State] in a class component using this.

@kaorun343
Copy link
Contributor

kaorun343 commented Dec 14, 2018

The key point is that when using TypeScript, you need to define properties not only for JS, runtime environment, but also for TS, static typing environment.

Such mapXxx helpers works only in runtime, so, in order to achieve this issue, please write each properties’ or methods’ type definitions.

@Component({
  computed: {
    ...mapGetters('ChartModule', {
      charts: 'getChars' // <- for runtime
    })
  }
})
class ChartComponent extends Vue {
  charts!: any[] // <- for static type checking

  created() {
    console.log(this.charts)
  }
}

@rostgoat
Copy link

rostgoat commented Mar 10, 2020

I tried both what @ktsn and @kaorun343 suggested but I am still kinda confused

getters.ts

export const GET_POSTS = 'GET_POSTS'

posts.module

import {GET_POSTS} from '../types/getters'
...
  get [GET_POSTS]() {
    return this.posts || [];
  }

PostsList.vue

@Component({
  components: { PostListItem },
  computed: mapGetters(["GET_POSTS"]) // what local prop does this map to or how do I access it?
})
export default class PostsList extends Vue {
  name = "PostsList";
  posts = [];

  /**
   * Get posts
   */
  async mounted() {
   console.log(this.GET_POSTS); // ERROR: Property 'GET_POSTS' does not exist on type 'PostsList'.
  }

essentially, I'm trying to do:

...mapGetters({
   posts: GET_POSTS
})

console.log(this.posts)

@yuicer
Copy link

yuicer commented May 26, 2020

any new progress here?

it seems mapGetters doesnot match class vue with well ts surport

@n1ywb
Copy link

n1ywb commented Dec 15, 2020

I think a MapGetter class property decorator would be just the thing here; something like

@MapGetter('Module/something') something: sometype;

@drasch
Copy link

drasch commented Jan 20, 2021

You can also convince Typescript by adding a object to extend:

const ChartComponentProps = Vue.extend({
  computed: {
    ...mapGetters('ChartModule', {
      charts: 'getChars' // <- for runtime
    })
  }
});

@Component
class ChartComponent extends ChartComponentProps {
  charts!: any[] // <- for static type checking

  created() {
    console.log(this.charts)
  }
}

@tryforceful
Copy link
Contributor

You can also convince Typescript by adding a object to extend:

const ChartComponentProps = Vue.extend({
  computed: {
    ...mapGetters('ChartModule', {
      charts: 'getChars' // <- for runtime
    })
  }
});

@Component
class ChartComponent extends ChartComponentProps {
  charts!: any[] // <- for static type checking

  created() {
    console.log(this.charts)
  }
}

This is nice to make things work, but of course it includes no type safety for these mapped getters, as they are all implicitly of type any when imported this way.

@drasch
Copy link

drasch commented Mar 4, 2021

Thanks. Didn't realize it was coming in as any

@strom-und-spiele
Copy link

You can simply type it instead of using any.

@Component({ computed: { ...mapGetters(["fooThing"]) } })
export default class FooComponent extends Vue {
  public fooThing!: Foo; // <- note the `!` which tells ts we care for this value being set.
  created() { console.log(this.fooThing) }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests