A header image for the blog

Here at Ionic, we’re big fans of TypeScript. Back when we were working on Ionic Framework 2.0, we made the move to go all in on TypeScript and haven’t looked back. When we shipped Ionic React, we made sure it used TypeScript out of the box and wrote about how to use TypeScript in a React app. Now with Ionic Vue, we’ve made the same choice to go all in on TypeScript and ship all our starter Vue projects with it. But we started to notice something interesting with the Vue Community: a bit of hesitation and in some cases a full on rejection of TypeScript. What’s the deal?

I did a very scientific poll and asked Vue developers if they were using Vue 3 and not using TypeScript, what was the reason. Thanks to all who replied!
Of the replies I got, the most common trend was that folks thought TypeScript was:

  • Too much work to configure
  • Didn’t “feel” like a good match
  • Just not for them

Now personal preference is one thing, but there are some technical assumptions being made that might be a result of bad experiences with older releases of TypeScript. So let’s actually look at what working with TypeScript in Vue project actually is like and the benefits you get by pairing Vue with TypeScript.

Types, what are they anyways?

Before we dive into the Vue parts, let’s just set a baseline. TypeScript is a superset of JavaScript that provides types. So any valid JavaScript is also valid TypeScript. For instance, if we have this bit of code:

const items = [0, 1, 2, 3]

We could load this in a JavaScript or TypeScript file without any issues. Where it gets fun is when you start to add the type information to this. We could add a type annotation that just tells TypeScript what kind of variable items is.

const items: number[] = [0, 1, 2, 3]

This is telling TypeScript that items is an Array (the [] part) and that it can only accept numbers. Why do we need this? Doesn’t JavaScript already understand this type of information?

JavaScript already has a loose sense of types, but it’s not strict. Meaning that we could have our variable accept anything; strings, objects, other arrays, etc. The problem here is that when we start to build out our apps, having things be this dynamic can lead to various runtime errors or just general confusion about what kind of data we’re working with.

But by utilizing types, we can make sure that we’re writing safe apps and can understand our code (even months later). To make this adoption event more approachable, TypeScript will auto-infer the types for us, so we often don’t even need to supply types if we’re setting the value right away. So our array example from before can drop the type annotation and be closer to regular JavaScript.

The basic types we deal with are number, strings, boolean, [](array), and {} (object). With these base types, we can provide TypeScript with all the information it needs to fully understand our code. There’s a lot more information regarding TypeScript that can be found on the official website.

Types in Vue

With the basic understanding of what types are, how do we get TypeScript working in our Vue project? Well if we’re using the Vue CLI for your project (which you should be), you can run this command from you terminal:

vue add typescript

This will kick off a Vue CLI plugin that gets our project setup for TypeScript. You’ll be prompted with a few questions along the way as well

? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Convert all .js files to .ts? No
? Allow .js files to be compiled? Yes
? Skip type checking of all declaration files (recommended for apps)? Yes

These prompts (with my answers included) will help you configure your project with TypeScript.

Two prompts I do want to call out are the “Convert .js to .ts” and “Allow .js files to be compiled”. If you’re migrating from an older project or have a lot of code that you do not want to migrate to just yet, these options are your best friends. These give you the benefits of TypeScript (compile time error checking and type information) without having to go all in on TypeScript.

Why Types in Vue?

So why would we want types in Vue? Well if having type-safe code and no runtime errors aren’t enough to convince you, what about a better understanding of Vue components? For me, this was one of the biggest reasons I opt for TypeScript when working with Vue. Take this basic HelloWorld component:

<template>
    <h1>Hello World</h1>
    <button @click="logVal()">Click Here</button>
</template>

<script>
  export default {
    name: "HelloWorld",
    methods: {
      logVal(){
    console.log("Hello from method")
      }
    }
  }
</script>

When I was first learning Vue, I was constantly forgetting the syntax for methods, props, etc. As someone who came from Angular and React, the syntax was confusing and took a bit to learn. Even typing this right now, I had to look up and verify I did it correctly! TypeScript provides a way to resolve all of that and make understanding Vue components straight forward.

First we import defineComponent from vue. This is essentially an empty function, but provides the type information we need to understand our component.

import { defineComponent } from 'vue';

Next, we can just wrap our component in this defineComponent function.

export default defineComponent({
  name: "HelloWorld",
  methods: {
    logVal(){
      console.log("Hello from method")
    }
  }
});

Once done, we can automatically start getting type information in our editor for our components.

“Ok Mike, are you serious about that?” While trivial, this can be a big feature for people just starting to learn Vue. It’s essentially having the Vue docs right in your editor. You know exactly how methods should be declared and what life cycle hooks are part of your components.

For more advanced use cases, like working with Vuex, TypeScript should almost be required. Being able to provide the expected values and types in your state management really just streamlines the whole process. The Vuex team has provided some great docs here for how to type your store and some best practices, plus I’ll be following this post up with some more material in the coming weeks.

Revisiting TypeScript

There are a lot of benefits to using TypeScript in your Vue app. But it is true, not everyone may need it. If you’re not using the Vue CLI or do not have a build process, using TypeScript can be a bit too much. But these cases are very few, especially when building apps, like with Ionic Vue. So if you’re working with Vue 3, try it out with TypeScript enabled. With the latest defaults in the Vue CLI, you’ll be able to build your apps faster and without any runtime errors!

Signup for the Ionic Newsletter to get the latest news and updates!

Notable Replies

  1. I was pretty unhappy when Ionic 2 went with TypeScript, which I hadn’t learned yet. That made me put off upgrading from Ionic 1, which I eventually came to regret. Fast forward a few years later, and now I love TypeScript and Ionic 5. But I get why people would hesitate. It’s a lot to change all at once.

  2. I mean, it’s not always a lot. I specifically call out parts in my post where typescript will do most of the type checking for you automatically.

  3. Thanks for an awesome intro to the main benefits of Typescript.

    As a Dev new to Vue and Ionic at once Typescript felt like just another thing to learn at first. I’ve come to enjoy TS mostly. But here and there I run into Typescript errors that take 30-90min to solve at best. The last ones took days, I’m still searching. It’s particularly frustrating in such cases if you pop open JsFiddle and your code works 100% out of the box. Then stick it back in the project and run into heaps of errors you don’t understand. It’s probably where most of us go… wait a minute…

    I’ve grown to understand some of the most common TS errors and often look up the more obscure ones. But even then when you’re just starting out it’s not always immediately clear what TS is on about.

    This is especially pronounced in an Ionic Vue3 project where for some reason the TS errors refer to totally different line numbers than what is in the code. It seems from my digging that it’s an open bug at the moment. But this makes debugging very hit and miss and often directly leads to days in debugging. I know the past 3days in my latest Ionic project where just spent hunting TS errors. I often just revert with git and start from the past checkpoint. If that means redoing 1-3days of work it’s often worth it compared to guessing what line number TS is throwing errors on. As a Dev new to Vue and Ionic I don’t exactly type this out in VIm like you do ;-). I also probably make some of the most obvious mistakes.

    Lately I code and check line by line so I catch TS errors early on while I’m still coding a new line.

    I think in time though TS is going to prove to be an invaluable asset. So I’m gritting my teeth and bearing the growing pains. Less debugging on very obscure issues later on is certainly worth it.

  4. Just loving all these confessions!

    I converted after one project without TS (suffering many runtime pains) and disciplined myself to use Typescript. My confession is that I do cheat once in a while by using the any or unknown keyword, misleading Typescript and myself. That is why I add the comment “Hacky” to every line where I cheat.

    I might be mistaken, but in my (Angular) case, my editor (vs code) tells me where I go wrong in Typescript at the moment I type the mistake.

    I hardly look at the CLI output anymore these days. Nor am caught in Typescript messages in the browser that way. So hardly any need to look for line numbers due to TS issues. Runtime issues (if any) are mostly due to APIs and wrong logic

    The editor and the app end result are my focal points. Creating and checking line by line, as u also mention.

    Shouldn’t this also be possible for Vue, looking at the blog?

    Otherwise, one would think there is an issue with the TS transpiler?

  5. @mhartington Speaking as a new VueJs Developer in a first solo project TS causes extreme frustration when you spend 90% of productive time chasing implicit errors senselessly on working JS code. It’s Einstein’s definition of insanity.

    I’ve spent time pushing through TS primers and TS is not hard but it does require understanding for the underlying code you’re working with. I can code VanillaJS off the top of my head. The hard part is when you’re learning VueJS and Ionic and Capacitor and along comes TS errors for days on end with senseless nonsense. To a new IonicVue dev this negates all the gains of using a framework.

    So when you’re new to VueJs you’re forced to run before you crawl by this requirement. And I think this is where the Pushback from most of the VueJS crowd comes from. TS is inherently part of VueJs’ inner workings. So where appropriate it’s taught without much ceremony in Vuejs docs but you’re still free to mostly write VanillaJs almost everywhere else. I get why this might not be great in the long term.

    When coming to Ionic though there’s still virtually no documentation for Capacitor and Cordova plugins that work in a VueJs+TS context. All the JS examples in Cordova plugins and Ionic example pages break over and over when you pull them into IonicVue. In the beginning it’s not immediately clear why and there’s so many stacks and dependancies involved that it’s hard to say where things break down. TS errors have nonsensical definitions that are written to apply to such a broad audience that they really don’t help much.

    And then comes JS plugins like Quaggajs that replace depreciated Cordova Scanning plugins with no real Capacitor replacements yet. This leads to a new level of fun - no types definition. So not only do I have to type out my code but if I want to use the code of others I need to write type definitions for their code as well. This requires me to dig around in their code and try to figure out what they intended. The TS requirement effectively makes many JS modules completely useless in Ionic unless you want to spend even more fun time with TS.

    Since over 90% of my time is already invested in solving TS issues I’m more keen to actually do something in my code that contributes to the actual aim of my project.

    Effectively TS ads so much technical debt to a very tiny project that I may as well abandon the whole thing and move to a different framework.

    For me the issue is not so much TS as the frustration of TS issues stopping all progress in it’s tracks. I think including example snippets in the Docs alongside React and Angular snippets will go a long way to alleviating much of the frustration for new users. But it is the tip of the Iceberg. TS is an advanced topic and not really worth it for tiny projects or beginners because it ads a constant hurdle to getting work done.

    After spending some time getting to know TS I’m convinced I want to use it in the medium to long term but I can’t yet justify the time drain it creates in my project work.

    The further I go the more I see why TS is so unpopular with VueJs devs using Ionic.

Join the discussion on the Ionic Forum

1 more reply

Participants