Vue.js TypeScript Support: Guide for Development and Tooling
The Vue CLI provides built-in TypeScript tooling support.
Official Declaration in NPM Packages
A static type system can help prevent many potential runtime errors when building applications, especially as applications grow. This is why Vue ships with official type declarations for TypeScript- not just in Vue core alone, but also for vuex and vue-router as well.
Since these packages are published on NPM, and the lates TypeScript knows how to resolve type in an NPM package, this means that when a package is installed via NPM, we don't need any additional tooling to use TypeScript with Vue.
Recommended Configuration
// tsconfig.json
{
"compilerOptions": {
// this will align with Vue's browser support
"target": "es5",
// this will enable stricter inference for data properties on `this`
"strict": true,
// if using rollup or webpack 2+, in leveraging tree shaking:
"module": "es2015",
"moduleResolution": "node"
}
}
Note that we have to include strict:true (or at least noImplicitThis:true which is a part of the strict flag) to leverage type checking of this in component methods otherwise it will always be treated as any type.
Development Tooling
Project Creation
The Vue CLI 3 can generate new projects that use TypeScript. To start off:
- Install the Vue CLI, if it's not already installed in your PC
- This will create a new project, and then choose the "Manually select features" option
npm install --global @vue/cli
vue create my-project-name
Editor Support
Visual Studio Code is strongly recommended for developing Vue applications with TypeScript. This is because it provides great out-of-the-box support for TypeScript. If you will be using single-file-components, I recommended that you get the awesome Vetur extension, this will provide TypeScript inference inside SFCs and many other great features.
WebStorm is an alternative as it provides out-of-the-box support for both TypeScript and Vue.
Basic Usage
If we want to let TypeScript properly infer types inside Vue component options, we need to define components with Vue.component or Vue.extend:
import Vue from 'vue'
const Component = Vue.extend({
// type inference is enabled
})
const Component = {
// have type inference will not be enabled here,
// because TypeScript can't tell that this is options for a Vue component.
}
Class-Style Vue Components
In case you prefer a class-based API when declaring components, you could use the officially maintained vue-class-component decorator:
import Vue from 'vue'
import Component from 'vue-class-component'
// The @Component decorator indicates that the class is a Vue component
@Component({
// All component options will be allowed in here
template: '<button @click="onClick">Click!</button>'
})
export default class MyComponent extends Vue {
// the initial data can be declared as instance properties
message: string = 'Hello!'
//The Component methods can be declared as instance methods
onClick (): void {
window.alert(this.message)
}
}
Augmenting Types for Use with Plugins
We can add plugins to Vue's global/instance properties and component options. In cases as these, type declarations are needed to make plugins to compile in TypeScript. There is a TypeScript feature that augments existing types called module augmentation.
Take for instance, if we want to declare an instance property $myProperty with type string:
// 1. Make sure to import 'vue' before declaring augmented types
import Vue from 'vue'
// 2. Specify a file with the types you want to augment
// Vue.JS has the constructor type in types/vue.d.ts
declare module 'vue/types/vue' {
// 3. Declare the augmentation for Vue
interface Vue {
$myProperty: string
}
}
After including the above code as a declaration file (like my-property.d.ts) in our project, we can use $myProperty on a Vue instance.
var vm = new Vue()
console.log(vm.$myProperty) // This should hopefully compile successfully
We can also declare additional global properties and component options:
import Vue from 'vue'
declare module 'vue/types/vue' {
// the global properties can be declared on
// the `VueConstructor` interface
interface VueConstructor {
$myGlobal: string
}
}
// the ComponentOptions is declared in types/options.d.ts
declare module 'vue/types/options' {
interface ComponentOptions<V extends Vue> {
myOption?: string
}
}
The above declarations will allow the following code to be compiled:
// Global property
console.log(Vue.$myGlobal)
// Additional component option
var vm = new Vue({
myOption: 'Hello'
})
Annotating Return Types
Due to the circular nature of Vue's declaration files, TypeScript may have some difficulties inferring the types of certain methods. Hence, we may need to annotate the return type on methods like render and those in computing.
import Vue, { VNode } from 'vue'
const Component = Vue.extend({
data () {
return {
msg: 'Hello'
}
},
methods: {
// we need annotation due to `this` in return type
greet (): string {
return this.msg + ' world'
}
},
computed: {
// need annotation
greeting(): string {
return this.greet() + '!'
}
},
//the `createElement` is inferred, but `render` will need return type
render (createElement): VNode {
return createElement('div', this.greeting)
}
})
If we find type inference or that member completion isn't working, then annotating certain methods may help address these problems. Use of the --noImplicitAny option will help find many of these unannotated methods.
Previous:
Vue.js Unit Testing: Guide with Jest and Vue Test Utils.
Next:
Vue.js Production Deployment: Best Practices and Configuration.
It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.
https://www.w3resource.com/vue/typescript-support-guide.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics