Preetish HS
Aug 17, 2022 ⋅ 7 min read

How to use Vue 3 with TypeScript

Preetish HS Freelance web developer, digital nomad, and design enthusiast. You can find me online at preetish.in.

Recent posts:

Understanding Solid Js Props A Complete Guide From Beginner To Advanced

Understanding SolidJS props: A complete guide

Let’s see how SolidJS props work to promote component reusability, exploring basic to advanced concepts for a complete understanding.

Temitope Oyedele
Dec 7, 2023 ⋅ 11 min read
Eleventy Vs. Next.js Static-Site Generation

Eleventy vs. Next.js for static site generation

We evaluate Eleventy and Next.js and compare both static site generators in terms of performance, developer experience, scalability, and ecosystem.

Nelson Michael
Dec 7, 2023 ⋅ 11 min read
Build Full-Stack App React Goxygen

Build a full-stack app with React and Goxygen

We show how to use Goxgen to scaffold a full-stack React app. See how to integrate React with Go and modify Goxygen to suit your project requirements.

Clara Ekekenta
Dec 6, 2023 ⋅ 8 min read
Express Js Adoption Guide Overview Examples Alternatives

Express.js adoption guide: Overview, examples, and alternatives

Express.js is a Node.js framework for creating maintainable and fast backend web applications in JavaScript. In the fast-paced world of […]

Antonello Zanini
Dec 6, 2023 ⋅ 17 min read
View all posts

30 Replies to "How to use Vue 3 with TypeScript"

  1. Nice! Filling in the typescript gaps between vuex and vue components is very important. Is there a way of gracefully getting this to work with action and getters in the root store as well?

    const store = new Vuex.Store({
    actions: {}, // Can’t make use of decorators
    getters: {}, // Can’t make use of decorators
    modules: {

  2. If you are using actions and getters in your root store, you will be able to access it directly like this

    import {
    } from ‘vuex-class’

    export class MyComp extends Vue {

    @Getter(‘foo’) getterFoo
    @Action(‘foo’) actionFoo

    created () {



  3. Thank you for this article! I am new, and with this topic I find the offical docu not so good as its reputation would make me expect.

    However, I do get lost, when you import “Project” and later set it as a component as “project” (lowercase). That doesn’t work in my case. Shouldn’t the component be written in uppercase, too?

  4. And I get a ton off errors when defining the @Props:

    ERROR in /Volumes/_II_/_SITES/vue_chord_player/src/components/Keyboard.vue(15,43):
    15:43 Property ‘name’ has no initializer and is not definitely assigned in the constructor.
    13 | export default class Keyboard extends Vue {
    14 | @Prop() readonly msg!: string
    > 15 | @Prop({ default: ‘John Doe’ }) readonly name: string
    | ^

    This is weird, because I do follow your setup completely… what is wrong here?

  5. Hi, I applaud anybody who is spreading information about how to get typescript and vue working. Until Vue 3.0 comes out, it is not an easy thing to do. I have been working on my learning of it for the past 2 -3 months. My top two requirements were to use typescript (preferably classes) and unit testing.

    I early on came to the conclusion that the proper solution at this point in time is to use the composition API and not the options API or the class API for Vue components. The composition API is the way forward for typescript in Vue and we can start using it today with the composition api plugin. And it makes your code very easy to separate the logic from the presentation so both can easily be unit tested. I have been defining all my logic of a vue in a class that gets instantiated in the vue component’s setup function and the class’ variables are defined as Refs for reactivity. It works great and unit testing it is so easy. it also allows you to separate different parts of the component’s logic into different classes so those items can be unit tested independently.

    For global state, I tried vuex-module-decorators and gave up. They seem to work at first, but once you start trying to do error handling of actions, both in production code and unit tests, you start to get strange errors from the decorator code. There is an SO thread an issue on github about it. This issue was the thing that finally made me abandon vuex. It just isn’t architected well to work with a typed language like typescript and I don’t want to give up the type safety and tooling support of typescript by casting everything everywhere. So now that I don’t use vuex, I have started to create typescript classes that are singletons as my global state and I import these modules wherever I need them. It works perfectly and I get typesafety because they are just classes. And they are incredibly easy to unit test. I don’t have to do anything special.

    Now that i have done all that, Vue and typescript work really well together.

    My biggest recommendation would be to ditch vuex. I would say that 80% of my time learning vue was trying all the different approaches to typescript and vuex. It all felt like banging my head against the wall

  6. This is great! please keep this article alive for as long as possible. please note this is in my bookmarks as i refer to it every time i am stuck

  7. I can not thank you enough bro, the provided link(GitHub repo) has helped me a-lot to spot some of thinks that did not sink well while following your tutorial. Thanks man

  8. Hi first of all thanks for the nice article.

    Unfortunately I didn’t manage to run your example with Vuex. The action updateName doesn’t get triggered. I remmember when I tried Vuex for the first time with plain Javascript, I had no problems, but somehow I thing with typescript it makes things 100 times more difficult.

  9. I completely agree. I could do this with typescript so easily and now things got much worse in my opnion. Maybe I just have to get used to it.

  10. Can you share a repo for how it works without Vuex? The repos shared here are my only reference. Now newly thinking up a new way of doing things makes my brain explode^^

  11. I’m hitting issues now with this, when I use an action I’m getting:

    ERR_ACTION_ACCESS_UNDEFINED: Are you trying to access this.someMutation() or this.someGetter inside an @Action?
    That works only in dynamic modules.
    If not dynamic use this.context.commit(“mutationName”, payload) and this.context.getters[“getterName”]

    In even the simplest examples like the above that are definitely using this.context.commit, anyone got any ideas?

  12. NOTE: Be careful, getters in vuex are not reactive. Loaded just once when the component is created.
    To access a data reactively, use this syntax
    syntax: this.$store.state.{CLASSNAME}.{MEMBER_OF_CLASS}
    example: this.$store.state.User.name
    to put in the component which you want access at the data.

  13. I use class components with decorators. Except for vuex and vuex modules I do not use decorators. Do not need them and all works fine, no errors.
    I understood that when application grows also vuex is needed in Vue 3, So I stay at Vue 2 with typescript for now.

    1. We try to stay abreast of new releases and update our content accordingly when there are breaking changes. We’ll keep this on our radar. Thanks!

Leave a Reply