22. TypeScript Support(打印稿支持)
TypeScript支持
在Vue 2.5.0+中,我们大大改进了我们的类型声明,以使用默认的基于对象的API。同时它引入了一些需要升级操作的更改。阅读此博客文章了解更多详情。
NPM软件包中的官方声明
静态类型系统可以帮助防止许多潜在的运行时错误,特别是在应用程序增长时 这就是为什么Vue 为TypeScript提供正式类型声明的原因- 不仅在Vue核心中,而且在vue-router和vuex中也是如此。
由于它们是在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: true
是strict
标志的一部分)才能利用this
组件方法中的类型检查,否则它总是被视为any
类型。
有关更多详细信息,请参阅TypeScript编译器选项文档。
开发工具
对于使用TypeScript开发Vue应用程序,我们强烈建议使用Visual Studio Code,它为TypeScript提供了很好的开箱即用支持。
如果您使用的是单文件组件(SFC),请获取令人敬畏的Vetur扩展,该扩展在SFC中提供了TypeScript推断以及许多其他强大功能。
基本用法
要让TypeScript正确推断Vue组件选项中的类型,您需要使用Vue.component
or 定义组件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
选项将有助于找到许多这些未经注释的方法。