22. TypeScript Support(打印稿支持)

TypeScript支持

在Vue 2.5.0+中,我们大大改进了我们的类型声明,以使用默认的基于对象的API。同时它引入了一些需要升级操作的更改。阅读此博客文章了解更多详情。

NPM软件包中的官方声明

静态类型系统可以帮助防止许多潜在的运行时错误,特别是在应用程序增长时 这就是为什么Vue 为TypeScript提供正式类型声明的原因- 不仅在Vue核心中,而且在vue-routervuex中也是如此。

由于它们是在NPM发布的,并且最新的TypeScript知道如何解决NPM包中的类型声明,这意味着通过NPM安装时,不需要任何额外的工具就可以使用TypeScript和Vue。

我们还计划vue-cli在不久的将来为Vue + TypeScript项目搭建一个可选项目。

推荐配置

// tsconfig.json { "compilerOptions": { // this aligns with Vue's browser support "target": "es5", // this enables stricter inference for data properties on `this` "strict": true, // if using webpack 2+ or rollup, to leverage tree shaking: "module": "es2015", "moduleResolution": "node" } }

请注意,您必须包含strict: true(或者至少noImplicitThis: truestrict标志的一部分)才能利用this组件方法中的类型检查,否则它总是被视为any类型。

有关更多详细信息,请参阅TypeScript编译器选项文档

开发工具

对于使用TypeScript开发Vue应用程序,我们强烈建议使用Visual Studio Code,它为TypeScript提供了很好的开箱即用支持。

如果您使用的是单文件组件(SFC),请获取令人敬畏的Vetur扩展,该扩展在SFC中提供了TypeScript推断以及许多其他强大功能。

基本用法

要让TypeScript正确推断Vue组件选项中的类型,您需要使用Vue.componentor 定义组件Vue.extend

import Vue from 'vue' const Component = Vue.extend{ // type inference enabled }) const Component = { // this will NOT have type inference, // because TypeScript can't tell this is options for a Vue component. }

类风格的Vue组件

如果您在声明组件时更喜欢基于类的API,则可以使用官方维护的vue-class-component修饰器:

import Vue from 'vue' import Component from 'vue-class-component' // The @Component decorator indicates the class is a Vue component @Component{ // All component options are allowed in here template: '<button @click="onClick">Click!</button>' }) export default class MyComponent extends Vue { // Initial data can be declared as instance properties message: string = 'Hello!' // Component methods can be declared as instance methods onClick (): void { window.alert(this.message) } }

增加插件使用的类型

插件可能会添加到Vue的全局/实例属性和组件选项。在这些情况下,需要使用类型声明来使插件在TypeScript中编译。幸运的是,还有一个TypeScript功能来增强现有的称为模块增强的类型。

例如,$myProperty要用类型声明一个实例属性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 has the constructor type in types/vue.d.ts declare module 'vue/types/vue' { // 3. Declare augmentation for Vue interface Vue { $myProperty: string } }

在将上述代码作为声明文件(如my-property.d.ts)包含在项目中之后,可以$myProperty在Vue实例上使用。

var vm = new Vue() console.log(vm.$myProperty) // This should compile successfully

您还可以声明其他全局属性和组件选项:

import Vue from 'vue' declare module 'vue/types/vue' { // Global properties can be declared // on the `VueConstructor` interface interface VueConstructor { $myGlobal: string } } // ComponentOptions is declared in types/options.d.ts declare module 'vue/types/options' { interface ComponentOptions<V extends Vue> { myOption?: string } }

上面的声明允许编译下面的代码:

// Global property console.log(Vue.$myGlobal) // Additional component option var vm = new Vue{ myOption: 'Hello' })

注释返回类型

由于Vue声明文件的循环性质,TypeScript可能难以推断某些方法的类型。

出于这个原因,你可能需要注释像方法的返回类型render和那些在computed

import Vue, { VNode } from 'vue' const Component = Vue.extend{ data() { return { msg: 'Hello' } }, methods: { // need annotation due to `this` in return type greet(): string { return this.msg + ' world' } }, computed: { // need annotation greeting(): string { return this.greet() + '!' } }, // `createElement` is inferred, but `render` needs return type render(createElement): VNode { return createElement('div', this.greeting) } })

如果您发现类型推断或成员完成不起作用,则注释某些方法可能有助于解决这些问题。

使用该--noImplicitAny选项将有助于找到许多这些未经注释的方法。