Is Vue.js really ready for TypeScript?

Is Vue.js really ready for TypeScript?

Vue.js is an amazing JS framework for creating UI on the web. TypeScript is a language that brought the type checking into JavaScript. To be honest I love both. I love Vue simplicity and how TypeScript brings JavaScript flexibility and type checking into one language. That is the reason why I was so happy that Vue.js 2.5 has become “TypeScript friendly”. But after a few months of using both of them together, my enthusiasm is gone. And now I want to share with you what happened.

TL;DR

Is Vue.js ready for TypeScript? Not really.

Creating Vue.js and TypeScript project

Creating a new project with both of these technologies takes about 30 seconds with VUE CLI. All you need to do is type the code below this paragraph and select TypeScript as one of your desired features. You will be asked if you want to use the class style syntax. I will cover this in the next section.

npm install -g @vue/cli
# OR
yarn global add @vue/cli
vue create hello-typescript

And that’s it. One could not even believe how easy is to work with VUE CLI 3. Everything is out of the box set up for us. And not only that! Also all your data, methods, computed properties, lifecycle methods etc. are strongly typed with TypeScript.

Two different syntaxes — class components vs standard syntax

When using TypeScript with Vue there are two main possibilities how your code can look like. You can either use the standard syntax or you can use the class style with decorators. The secondly mentioned syntax is different in the following points (taken from the original documentation on the GitHub)

  1. methods can be declared directly as class member methods.
  2. Computed properties can be declared as class property accessors.
  3. Initial data can be declared as class properties.
  4. data, render and all Vue lifecycle hooks can be directly declared as class member methods as well, but you cannot invoke them on the instance itself. When declaring custom methods, you should avoid these reserved names.
  5. For all other options, pass them to the decorator function.
Standard syntax vs class style syntax

What is better?

For the first project in our company, I’ve chosen the standard way because I didn’t want to completely change the syntax of the Vue component. I thought that this would make the switch from JavaScript to TypeScript easier. That was a mistake. I would not suggest you to do the same. Without the class style syntax, you will not be able to use some helpful Vue-TypeScript libraries (like vuex-class). And what is even more important is that you will not be able to use some of the Vue features like helpers from Vuex ( mapGetters, mapMutation ...) and mixins.

Documentation

In my opinion documentation of Vue.js with Typescript is poor. You will not be able to find examples for many different scenarios. StackOverflow will not help you much either. You will be alone — it seems like not many people are using Vue with Typescript. Let me know if you know any product that was written with these technologies.

Using third-party libraries

Another issue is that almost all of the libraries that we were using did not have typings. DefinitelyTyped is not very helpful either. Our projects usually end up full of .d.ts files exporting any as a type. Sometimes you have to extend the Vue interface because a library added a new prop to the Vue instance. At that moment TypeScript is not very useful, right?

Templates

Templates are not typed at all. In every project, there are a lot of dummy components that are just presenting data received by props. When you change the data structure, TypeScript will not notice anything wrong. At that moment, TypeScript is losing its power again.

Props

Everything with props works as expected until you try to use TypeScript interface or Array. There is a hidden/undocumented way how to use TS interface in prop type (you can read more here) but you will not be able to use Array at all — there is very serious bug connected with this problem. Pull request with the solution is on the way but we are not there yet. So, for now, we can not use Array as a prop type which leads to a lot of warning about the wrongly passed type to a prop in the console. If you use class style syntax, you can use@Propdecorator but that will not work if you are using Babel alongside TypeScript (for auto-detecting polyfills).

Vuex

Vuex action, mutations etc itself are strongly typed. Which is great, but when you are calling these actions from a component you can put literary anything into the payload and the compiler will not complain. Same when getting the state. And typescript is weaker again…

Summary

Like I said before I love both of these technologies. But it seems that when you combine Vue and TypeScript together they are both losing its power. Using TypeScript with Vue can still give you some benefits, but the power of the TypeScript is very limited. If you choose using them together, I would definitely suggest using the class style syntax.

It seems that when you combine Vue and TypeScript together they are both losing its power.

Future

In my opinion, most of these drawbacks will be fixed in the future. Vue 3 will be completely rewritten in TypeScript and that could change a lot. But if we want TypeScript to work seamlessly we have to start using it more. It is not going to be more useful if no libraries exports typings.


I would love to hear your feedback

Let me know what you think. If you have any idea how to work around any of the disadvantages I was talking about I would love to hear that! And if you have any Vue.js TypeScript product in production let us know how you feel about that. If you like this post, I will appreciate every single thumb :)