首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

22. TypeScript Support(打印稿支持)

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

NPM软件包中的官方声明

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

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

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

推荐配置

代码语言:javascript
复制
// 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

代码语言:javascript
复制
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修饰器:

代码语言:javascript
复制
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

代码语言:javascript
复制
// 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实例上使用。

代码语言:javascript
复制
var vm = new Vue()
console.log(vm.$myProperty) // This should compile successfully

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

代码语言:javascript
复制
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
  }
}

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

代码语言:javascript
复制
// Global property
console.log(Vue.$myGlobal)

// Additional component option
var vm = new Vue({
  myOption: 'Hello'
})

注释返回类型

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

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

代码语言:javascript
复制
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选项将有助于找到许多这些未经注释的方法。

扫码关注腾讯云开发者

领取腾讯云代金券