TypeScript 支援


Vue CLI 提供了内建的 TypeScript 工具支持。


目录


发布为 NPM 包的官方声明文件


静态类型系统能帮助你有效防止许多潜在的运行时错误,而且随着你的应用日渐丰满会更加显著。这就是为什么 Vue 不仅仅为 Vue core 提供了针对 TypeScript官方类型声明,还为 Vue RouterVuex 也提供了相应的声明文件。

而且,我们已经把它们发布到了 NPM,最新版本的 TypeScript 也知道该如何自己从 NPM 包里解析类型声明。这意味着只要你成功地通过 NPM 安装了,就不再需要任何额外的工具辅助,即可在 Vue 中使用 TypeScript 了。



// tsconfig.json
{
  "compilerOptions": {
    // 与 Vue 的浏览器支持保持一致
    "target": "es5",
    // 这可以对 `this` 上的数据属性进行更严格的推断
    "strict": true,
    // 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake:
    "module": "es2015",
    "moduleResolution": "node"
  }
}

注意你需要引入 strict: true (或者至少 noImplicitThis: true,这是 strict 模式的一部分) 以利用组件方法中 this 的类型检查,否则它会始终被看作 any 类型。

参阅 TypeScript 编译器选项文档 (英) 了解更多。


开发工具链



工程创建

Vue CLI 3 可以使用 TypeScript 產生新工程。建立方式:

# 1. 如果没有安装 Vue CLI 就先安装
npm install --global @vue/cli

# 2. 创建一个新工程,并选择 "Manually select features (手动选择特性)" 选项
vue create my-project-name


編輯器支援

##要使用TypeScript 開發Vue 應用程序,我們強烈建議您使用

Visual Studio Code,它為TypeScript 提供了極好的「開箱即用」支援。如果你正在使用單一檔案元件 (SFC), 可以安裝提供 SFC 支援以及其他更多實用功能的 Vetur 外掛程式

WebStorm 也為 TypeScript 和 Vue 提供了「開箱即用」的支援。


基本用法


#要讓TypeScript 正確推斷Vue 元件選項中的類型,您需要使用

Vue.componentVue.extend 定義元件:

import Vue from 'vue'
const Component = Vue.extend({
  // 类型推断已启用
})
const Component = {
  // 这里不会有类型推断,
  // 因为TypeScript不能确认这是Vue组件的选项
}





基於類別的Vue 元件


如果您在宣告元件時偏好基於類別的API,則可以使用官方維護的
vue-class-component

裝飾器:

import Vue from 'vue'
import Component from 'vue-class-component'

// @Component 修饰符注明了此类为一个 Vue 组件
@Component({
  // 所有的组件选项都可以放在这里
  template: '<button @click="onClick">Click!</button>'
})
export default class MyComponent extends Vue {
  // 初始数据可以直接声明为实例的属性
  message: string = 'Hello!'
  // 组件方法也可以直接声明为实例的方法
  onClick (): void {
    window.alert(this.message)
  }
}

增強類型以配合插件使用

##插件可以增加Vue 的全域/實例屬性和元件選項。在這些情況下,在 TypeScript 中製作插件需要類型聲明。慶幸的是,TypeScript 有一個特性來補充現有的類型,稱為

模組補充 (module augmentation)

例如,宣告一個
string

類型的實例屬性

$myProperty
// 1. 确保在声明补充的类型之前导入 'vue'
import Vue from 'vue'
// 2. 定制一个文件,设置你想要补充的类型
//    在 types/vue.d.ts 里 Vue 有构造函数类型
declare module 'vue/types/vue' {
// 3. 声明为 Vue 补充的东西
  interface Vue {
    $myProperty: string
  }
}
在你的專案中包含了上述作為聲明檔案的程式碼之後(像
my-property.d.ts

),你就可以在Vue 實例上使用
$myProperty

了。

var vm = new Vue()
console.log(vm.$myProperty) // 将会顺利编译通过
你也可以宣告額外的屬性和元件選項:
import Vue from 'vue'

declare module 'vue/types/vue' {
  // 可以使用 `VueConstructor` 接口
  // 来声明全局属性
  interface VueConstructor {
    $myGlobal: string
  }
}

// ComponentOptions 声明于 types/options.d.ts 之中
declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    myOption?: string
  }
}
上述的宣告允許下面的程式碼順利編譯通過:
// 全局属性
console.log(Vue.$myGlobal)

// 额外的组件选项
var vm = new Vue({
  myOption: 'Hello'
})

####### ########標註回傳值###############因為Vue 的宣告檔天生就具有循環性,TypeScript 可能在推斷某個方法的型別的時候有困難。因此,你可能需要在 ###render### 或 ###computed### 裡的方法上標註回傳值。 ######
import Vue, { VNode } from 'vue'

const Component = Vue.extend({
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    // 需要标注有 `this` 参与运算的返回值类型
    greet (): string {
      return this.msg + ' world'
    }
  },
  computed: {
    // 需要标注
    greeting(): string {
      return this.greet() + '!'
    }
  },
  // `createElement` 是可推导的,但是 `render` 需要返回值类型
  render (createElement): VNode {
    return createElement('div', this.greeting)
  }
})

如果你發現型別推導或成員補齊不工作了,標註某個方法也許可以幫助你解決這個問題。使用 --noImplicitAny 選項將會幫助你找到這些未標註的方法。