精读 Vue 官方文档系列 🎉
发布为 NPM 包的官方声明文件
Vue 已经为 Vue-core、Vuex、Vue-Router 提供了 NPM 包形式的类型声明文件,最新版本的 TypeScript 也知道自己该如何从 NPM 包里解析类型声明。
推荐配置
在 tsconfig.js 配置文件中,建议开启 strict:true 或至少 noImplicitThis: true,用来对组件方法中 this 的类型进行检查,否则它会始终被看作 any 类型。
基本用法
Vue2.x 创建的组件如果想能够被 TypeScript 正确识别其中的类型,则必须要使用 Vue.extend() 或 Vue.Component() 方法定义组件。
import Vue from 'vue'
const Component = Vue.extend({
// 类型推断已启用
});
const Component = {
// 这里不会有类型推断,
// 因为 TypeScript 不能确认这是 Vue 组件的选项
}
export default Vue.extend({
// 类型推断已启用
});
增强类型以配合插件使用
使用 TypeScript 的模块补充 (Module Augmentation) 特性,我们可以为 Vue 自定义的属性或方法进行类型的声明。这一点对于制作插件(Plugin) 来增加 Vue 的全局/实例 property 和组件选项的情况下非常有用。
例如,声明一个 string 类型的实例 property $myProperty:
// 1. 确保在声明补充的类型之前导入 'vue'
import Vue from 'vue'
// 2. 定制一个文件,设置你想要补充的类型
// 在 types/vue.d.ts 里 Vue 有构造函数类型
declare module 'vue/types/vue' {
// 3. 声明为 Vue 补充的东西
interface Vue {
$myProperty: string
}
}
在你的项目中包含了上述作为声明文件的代码之后,你就可以在 Vue 实例上使用 $myProperty 了。
var vm = new Vue()
console.log(vm.$myProperty) // 将会顺利编译通过
同样的操作,你也可以为 Vue 构造函数声明额外的全局的静态的 property:
delcare module 'vue/types/vue' {
interface VueConstructor {
$t:Translate | string
}
}
或者,声明额外的组件选项 (option):
delcare module 'vue/types/options' {
interface ComponentOptions<v extends Vue> {
myOption?: string
}
}
这时你就可以为组件定义自定义的组件选项,并通过 $options 来获取它们。
标注返回值
就像用 TypeScript 定义函数时声明函数的返回值类型,我们非常推荐对于 Vue 组件的 render 方法、methods 中定义的方法以及 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)
}
})
标注 Prop
关于组件选项 props 成员类型的声明:
基本数据类型 直接使用该类型的构造函数进行声明即可。
引用类型 需要借助 Vue 提供的 PropType 类型标注工具来详细描述每个成员的具体类型。
import Vue, { PropType } from 'vue'
interface ComplexMessage {
title: string,
okMessage: string,
cancelMessage: string
}
const Component = Vue.extend({
props: {
name: String,
success: { type: Number },
callback: Function as PropType<() => void>,
message: {
type: Object as PropType<ComplexMessage>,
required: true,
validator(message: ComplexMessage) {
return !!message.title;
}
}
}
})
注意
PropType工具只能与Vue.extend或者是Vue.Component结合使用,因为只有使用这两种方式创建的组件对象,其this才不是any。
除此之外,你也可以通过 TS 的类型断言结合函数声明的返回值方式来声明成员的详细类型。
export default Vue.extend({
name: "HelloWorld",
props: {
msg: Object as () => { name: string; key: number },
},
mounted() {
const p = this.msg;
p.name;
},
});