vue-type-check: type checking in the template part

4 minute read Published: 2019-10-02

Nowadays more people start trying to build Vue project with Typescript. Vue itself also provides better support to Typescript such as the vue-class-component lib and rewriting version 3.0's codebase in Typescript.

But the limitation of type checking in the template is still a big problem preventing Vue component from being type-safe.

We have just open-sourced an easy-to-use Vue type checker, vue-type-check, to help solve this problem. This type checker can do type checking on the template and script code of a Vue single-file-component.

And it also provides CLI and programmatical API usages with clear error messages which is helpful to integrate the existing workflows.

Example

We are going to check a simple Vue component with two type errors:

<template>
  <div id="app">
    <p>{{ msg }}</p>
  </div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  name: "app",
  data() {
    return {
      message: "Hello World!"
    };
  },
  methods: {
    printMessage() {
      console.log(this.message.toFixed(1));
    }
  }
});
</script>

example.gif

More details can be found in the doc.

How it works?

Currently, vue-type-check is built on the top of vetur's interpolation feature. You may find some internal designs of the interpolation in this post.

We decided to make vue-type-check because of some vetur's limitations:

We have tried other approaches before this, but finally, we choose to stick with vetur because we do not like over-wheeling, and want to keep bringing vetur's latest feature and optimization into vue-type-check.

Also, we found vetur has a plan for offering a CLI usage, so we will try to contribute to the upstream later.

Other attempts

The community also has other attempts on checking the types in the template. We have learned the trade-off of them in this post from katashin.

Approach 1: check the compiled template

Since Vue compiled the template into JS code, we can also implement a template to TS compiler and check the compiled code.

The limitation of this approach is that the vue-template-compiler does not have source map support so we could not get the position of the error in the source file.

Approach 2: implement a ad-hoc type checker

Like what Angular did, we could implement an ad-hoc type checker that can use part of Typescript's APIs.

But it would be extremely hard to implement some complex checks like generics and function overloading.

Approach 3: transform the template into Typescript AST

We can fully adapt the Typescript compiler's type checks in this way with source map support.

This approach is also choosed in Katashin's patch for vetur and it use vue-eslint-parser under the hood.