跳转到内容

使用TypeScript配合Vue

类似于TypeScript的类型系统可以在构建时通过静态分析检测许多常见错误。这降低了生产环境中运行时错误的可能性,并使我们能够更自信地对大规模应用程序中的代码进行重构。TypeScript还通过IDE中的基于类型的自动完成来提高开发者的用户体验。

Vue是用TypeScript编写的,并提供了第一级的TypeScript支持。所有官方Vue包都包含了捆绑的类型声明,应该可以直接使用。

项目设置

create-vue,官方的项目脚手架工具,提供了创建一个由Vite驱动、TypeScript就绪的Vue项目的选项。

概述

在基于Vite的设置中,开发服务器和打包器仅进行转译,不执行任何类型检查。这确保了即使在使用TypeScript的情况下,Vite开发服务器也能保持极快的速度。

  • 在开发过程中,我们建议依赖一个好的IDE设置来即时反馈类型错误。

  • 如果使用SFCs,请使用vue-tsc实用工具进行命令行类型检查和类型声明生成。vue-tsc是TypeScript的自身命令行接口的包装器。它基本上与tsc相同,除了它还支持Vue SFCs和TypeScript文件。您可以在Vite开发服务器并行运行的情况下以监控模式运行vue-tsc,或者使用像vite-plugin-checker这样的Vite插件,它在一个单独的工作线程中运行检查。

  • Vue CLI也提供了TypeScript支持,但不再推荐。请参阅下面的说明

IDE支持

  • Visual Studio Code (VS Code)因其对TypeScript的出色支持而强烈推荐。

    • Vue - Official (之前称为Volar)是官方的VS Code扩展,它提供了Vue SFC内的TypeScript支持,以及许多其他优秀功能。

      小贴士

      Vue - Official扩展替换了Vetur,我们之前官方的Vue 2 VS Code扩展。如果您已经安装了Vetur,请确保在Vue 3项目中禁用它。

  • WebStorm也提供了对TypeScript和Vue的即开即用支持。其他JetBrains IDE也支持它们,要么是即开即用,要么是通过一个免费插件。截至2023.2版本,WebStorm和Vue插件都内置了对Vue语言服务器的支持。您可以在设置 > 语言和框架 > TypeScript > Vue下将Vue服务设置为使用Volar集成在所有TypeScript版本上。默认情况下,Volar将用于5.0及更高版本的TypeScript。

配置tsconfig.json

通过create-vue构建的项目包括预配置的tsconfig.json。基本配置被抽象在@vue/tsconfig包中。在项目内部,我们使用项目引用来确保在不同环境中运行的代码具有正确的类型(例如,应用程序代码和测试代码应具有不同的全局变量)。

当手动配置tsconfig.json时,一些值得注意的选项包括

  • compilerOptions.isolatedModules被设置为true,因为Vite使用esbuild进行TypeScript的转译,并受限于单个文件转译。 compilerOptions.verbatimModuleSyntaxisolatedModules的超集,也是一个很好的选择——这是@vue/tsconfig所使用的。

  • 如果您使用的是Options API,则需要将compilerOptions.strict设置为true(或者至少启用compilerOptions.noImplicitThis,它是strict标志的一部分)以利用组件选项中this的类型检查。否则,this将被视为any

  • 如果您在构建工具中配置了解析器别名,例如在create-vue项目中默认配置的@/*别名,您还需要通过compilerOptions.paths为其配置TypeScript。

  • 如果您打算在Vue中使用TSX,请将compilerOptions.jsx设置为"preserve",并将compilerOptions.jsxImportSource设置为"vue"

另请参阅

关于Vue CLI和ts-loader的说明

在基于webpack的设置,例如Vue CLI中,通常将类型检查作为模块转换管道的一部分执行,例如使用ts-loader。然而,这并不是一个完美的解决方案,因为类型系统需要了解整个模块图来执行类型检查。单个模块的转换步骤根本不适合这项任务。它导致了以下问题

  • ts-loader只能检查转换后的代码。这与我们在IDE中看到的错误或来自vue-tsc的错误不匹配,这些错误直接映射回源代码。

  • 类型检查可能很慢。当它与代码转换在同一个线程/进程中执行时,它会显著影响整个应用程序的构建速度。

  • 我们已经在IDE中单独的进程中运行了类型检查,因此开发体验减速的成本并不是一个好的权衡。

如果您目前正在使用Vue 3 + TypeScript通过Vue CLI,我们强烈建议迁移到Vite。我们还在开发CLI选项以启用仅TS转译支持,这样您就可以切换到vue-tsc进行类型检查。

一般使用说明

defineComponent()

为了让TypeScript正确推断组件选项中的类型,我们需要使用defineComponent()来定义组件

ts
import { defineComponent } from 'vue'

export default defineComponent({
  // type inference enabled
  props: {
    name: String,
    msg: { type: String, required: true }
  },
  data() {
    return {
      count: 1
    }
  },
  mounted() {
    this.name // type: string | undefined
    this.msg // type: string
    this.count // type: number
  }
})

defineComponent() 还支持在未使用 <script setup> 的情况下,通过 Composition API 推断传递给 setup() 的 props。

ts
import { defineComponent } from 'vue'

export default defineComponent({
  // type inference enabled
  props: {
    message: String
  },
  setup(props) {
    props.message // type: string | undefined
  }
})

另请参阅

小贴士

defineComponent() 还为用纯 JavaScript 定义的组件启用了类型推断。

在单文件组件中的使用

要在 SFC 中使用 TypeScript,请向 <script> 标签添加 lang="ts" 属性。当存在 lang="ts" 时,所有模板表达式也享有更严格的类型检查。

vue
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  data() {
    return {
      count: 1
    }
  }
})
</script>

<template>
  <!-- type checking and auto-completion enabled -->
  {{ count.toFixed(2) }}
</template>

lang="ts" 也可以与 <script setup> 一起使用

vue
<script setup lang="ts">
// TypeScript enabled
import { ref } from 'vue'

const count = ref(1)
</script>

<template>
  <!-- type checking and auto-completion enabled -->
  {{ count.toFixed(2) }}
</template>

模板中的 TypeScript

当使用 <script lang="ts"><script setup lang="ts"> 时,<template> 也支持在绑定表达式中使用 TypeScript。这在需要在对模板表达式进行类型转换时非常有用。

以下是一个虚构的例子

vue
<script setup lang="ts">
let x: string | number = 1
</script>

<template>
  <!-- error because x could be a string -->
  {{ x.toFixed(2) }}
</template>

这可以通过内联类型转换来解决这个问题

vue
<script setup lang="ts">
let x: string | number = 1
</script>

<template>
  {{ (x as number).toFixed(2) }}
</template>

小贴士

如果使用 Vue CLI 或基于 webpack 的设置,模板表达式中的 TypeScript 需要 vue-loader@^16.8.0

与 TSX 一起使用

Vue 还支持使用 JSX / TSX 创建组件。详细信息请参阅 渲染函数 & JSX 指南。

泛型组件

泛型组件支持两种情况

API 特定食谱

使用 TypeScript 与 Vue 已加载