4x2 精读Vue官方文档 - TypeScript 支持

1,760 阅读2分钟

精读 Vue 官方文档系列 🎉

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

Vue 已经为 Vue-coreVuexVue-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;
    },
});