外觀
使用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.verbatimModuleSyntax
是isolatedModules
的超集,也是一個很好的選擇——這是@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 指南。
泛型元件
泛型元件支援兩種情況
- 在 SFC 中:
<script setup>
帶有generic
屬性 - 渲染函式 / JSX 元件:
defineComponent()
的函式簽名