Since 0.28.0, Vetur offers cross-file Prop Type Validation.

Docs are here. In short, this works with:

You can use VTI to get validation errors on CLI.

Some todos I plan to work on:

Here’s a quick demo. You can also clone octref/vue-prop-type-validation to play with it:

In the remainder of this post, I’ll touch upon these topics:

Why Prop Type Validation

To understand Prop Type Validation’s benefits, let’s take a look at two things. Vue’s prop type check and TypeScript’s benefits.

Vue’s prop type check doesn’t use TypeScript types and doesn’t generate errors on either IDE or CLI. If you pass a boolean to a string prop, you only get a warning in the browser console:

For TypeScript users, this doesn’t suffice. When people ask for “TypeScript support”, what they really mean is “tooling support”. Compiler that checks types. IDE that reveals type errors. Auto-completion of all properties in an object. Hover that shows type information. Reliable rename that works across the codebase.

When you are working on a pure TypeScript codebase, you feel every file is covered by the type system. If changing a type generates 20 errors, fixing these 20 errors is all you need to do to get the code running again. Not one more, not one less.

A Vue project, even written in TypeScript, still contains template code that is not covered by the type system. Sure you can write TSX, but Vue people like SFC and Vue templates. When you add, rename, change-type-of a prop, you do not know how many errors will such a change generate, and where such errors are. This limits your ability to refactor, which is essential to keeping a large codebase clean and organized.

Vetur’s Prop Type Validation fills the gap. Together with Generic Vue Template Interpolation Language Features, Vetur now provides auto-completion, type checking, jump-to-definition and find-references for Vue Single File Components. Refactor and rename need more work, but they’ll come as well.

Additionally:

This is similar to the TypeScript ecosystem:

With Prop Type Validation, I hope Vetur can help you navigate through complex Vue codebases and make changes with confidence.

How Prop Type Validation works

When you are editing a .vue file in Vetur, you can run the command Vetur: Show corresponding virtual file and sourcemap to view the internal TypeScript representation of the Vue file. This virtual TypeScript file powers Vetur’s Interpolation Support, and is now extended to support Prop Type Validation.

Given two Vue files, such as Child.vue and Parent.vue:

<!-- Child.vue -->
<script lang="ts">
import Vue, { PropType } from 'vue'

export default Vue.extend({
  props: {
    str: String as PropType<'foo' | 'bar'>,
    num: Number
  }
})
</script>
<!-- Parent.vue -->
<template>
  <child :str="myStr" :num="42"></child>
</template>

<script>
import Child from './Child.vue'
export default {
  components: {
    Child
  },
  props: {
    myStr: String,
    myNum: Number
  }
}
</script>

Vetur roughly translates Parent.vue into parent-vue-transformed.ts:

// parent-vue-transformed.ts
import Vue from 'vue'

const __vlsComponent = Vue.extend({
  props: {
    myStr: String,
    myNum: Number
  }
})

export declare const __vlsRenderHelper: {
  <T>(Component: (new (...args: any[]) => T), fn: (this: T) => any): any;
};
export interface __vlsComponentData<T> {
  props: Record<string, any>;
}
interface __vlsComponentData__child<T> extends __vlsComponentData<T> {
  props: { str: 'foo' | 'bar'; num: number; [other: string]: any }
}
declare const __vlsComponentHelper__child: {
  <T>(
    vm: T,
    tag: string,
    data: __vlsComponentData__child<Record<string, any>> & ThisType<T>,
    children: any[]
  ): any
}

__vlsRenderHelper(__vlsComponent, function () {
  __vlsComponentHelper__child(
    this,
    'child',
    { props: { str: this.myStr, num: 42 } },
    []
  )
})

If you open this TS file in VS Code, you’ll see an error on str: this.myStr, saying Type 'string' is not assignable to type '"foo" | "bar"'.

What Vetur does is to:

Sponsorship and continued development

When I left US and my work at Microsoft, I decided to give more time to my personal researches and pursuits, and only commit at most 15 hours/week to Open Source. Prop Type Validation took way more time and energy than I expected, but I still tried to finish it because I believe this feature makes Vue great. Through VLS, Prop Type Validation will be made available to Atom, Sublime Text, Vim/Neovim, OniVim, Emacs and CodeSandbox. I hope it helps you enjoy Vue.

I want to offer my thank-you to all my sponsors. Special thank-yous to Katashin who implemented the original template interpolation transformer, to Yoyo who made a lot of high-quality contributions recently to Vetur, and to Evan who has been sponsoring my work while delivering a great Vue 3. Your support gives me momentum to push Vetur further.

This year I’m applying to grad school. The earliest deadline is Dec 1. I’ll try to allocate some time for Vetur, but I’ll have to prioritize my application over Open Source for the next few months.

With pressure from applying to graduate school and from not having a regular paying job, I find it harder and harder to commit more time to Vetur. If you find Vetur useful, please consider sponsoring my continued development to lessen my financial burden. Thank you.

A map of my sponsors, updated daily. I feel incredibly fortunate to be receiving support coming from five continents…thank y’all.

#tech