TypeScript 支持

    随着应用的增长,静态类型系统可以帮助防止许多潜在的运行时错误,这就是为什么 Vue 3 是用 TypeScript 编写的。这意味着在 Vue 中使用 TypeScript 不需要任何其他工具——它具有一流的公民支持。

    推荐配置

    请注意,必须包含 strict: true (或至少包含 noImplicitThis: true,它是 strict 标志的一部分) 才能在组件方法中利用 this 的类型检查,否则它总是被视为 any 类型。

    参见 查看更多细节。

    Vue CLITypeScript 支持 - 图1 (opens new window) 可以生成使用 TypeScript 的新项目,开始:

    1. # 1. Install Vue CLI, 如果尚未安装
    2. npm install --global @vue/cli@next
    3. # 2. 创建一个新项目, 选择 "Manually select features" 选项
    4. vue create my-project-name
    5. # 3. 如果已经有一个不存在TypeScript的 Vue CLI项目,请添加适当的 Vue CLI插件:
    6. vue add typescript

    请确保组件的 script 部分已将语言设置为 TypeScript:

    1. <script lang="ts">
    2. ...
    3. </script>

    编辑器支持

    对于使用 TypeScript 开发 Vue 应用程序,我们强烈建议使用 ,它为 TypeScript 提供了很好的开箱即用支持。如果你使用的是单文件组件 (SFCs),那么可以使用很棒的 ,它在 SFCs 中提供了 TypeScript 推理和许多其他优秀的特性。

    定义 Vue 组件

    要让 TypeScript 正确推断 Vue 组件选项中的类型,需要使用 defineComponent 全局方法定义组件:

    1. import { defineComponent } from 'vue'
    2. const Component = defineComponent({
    3. // 已启用类型推断
    4. })

    TypeScript 应该能够在不显式定义类型的情况下推断大多数类型。例如,如果有一个具有数字 count property 的组件,如果试图对其调用特定于字符串的方法,则会出现错误:

    如果你有一个复杂的类型或接口,你可以使用 type assertion (opens new window) 对其进行强制转换:

    1. interface Book {
    2. title: string
    3. author: string
    4. year: number
    5. }
    6. const Component = defineComponent({
    7. data() {
    8. return {
    9. book: {
    10. title: 'Vue 3 Guide',
    11. year: 2020
    12. } as Book
    13. }
    14. }
    15. })

    由于 Vue 声明文件的循环特性,TypeScript 可能难以推断 computed 的类型。因此,你可能需要注释返回类型的计算属性。

    1. const Component = defineComponent({
    2. data() {
    3. return {
    4. message: 'Hello!'
    5. }
    6. },
    7. computed: {
    8. // 需要注释
    9. greeting(): string {
    10. return this.message + '!'
    11. }
    12. // 在使用setter进行计算时,需要对getter进行注释
    13. greetingUppercased: {
    14. get(): string {
    15. return this.greeting.toUpperCase();
    16. },
    17. set(newValue: string) {
    18. this.message = newValue.toUpperCase();
    19. },
    20. },
    21. }
    22. })

    注释 Props

    Vue 对定义了 type 的 prop 执行运行时验证。要将这些类型提供给 TypeScript,我们需要使用 PropType 强制转换构造函数:

    1. import { defineComponent, PropType } from 'vue'
    2. interface ComplexMessage {
    3. title: string
    4. okMessage: string
    5. cancelMessage: string
    6. }
    7. const Component = defineComponent({
    8. props: {
    9. name: String,
    10. callback: {
    11. type: Function as PropType<() => void>
    12. },
    13. message: {
    14. type: Object as PropType<ComplexMessage>,
    15. required: true,
    16. return !!message.title
    17. }
    18. }
    19. }
    20. })

    如果你发现验证器没有得到类型推断或者成员完成不起作用,那么用期望的类型注释参数可能有助于解决这些问题。

    与 Composition API 一起使用

    Refs 根据初始值推断类型:

    1. import { defineComponent, ref } from 'vue'
    2. const Component = defineComponent({
    3. setup() {
    4. const year = ref(2020)
    5. const result = year.value.split('') // => Property 'split' does not exist on type 'number'
    6. }
    7. })

    有时我们可能需要为 ref 的内部值指定复杂类型。我们可以在调用 ref 重写默认推理时简单地传递一个泛型参数:

    1. const year = ref<string | number>('2020') // year's type: Ref<string | number>
    2. year.value = 2020 // ok!

    TIP

    如果泛型的类型未知,建议将 ref 转换为 Ref<T>

    类型声明 reactive

    当声明类型 reactive property,我们可以使用接口:

    1. import { defineComponent, reactive } from 'vue'
    2. interface Book {
    3. title: string
    4. year?: number
    5. }
    6. export default defineComponent({
    7. name: 'HelloWorld',
    8. setup() {
    9. const book = reactive<Book>({ title: 'Vue 3 Guide' })
    10. // or
    11. const book: Book = reactive({ title: 'Vue 3 Guide' })
    12. // or
    13. const book = reactive({ title: 'Vue 3 Guide' }) as Book
    14. }

    计算值将根据返回值自动推断类型