如果有任何問題或建議,歡迎隨時聯繫我:
各位 Vue 的魔法師們!專案一直以來都由 JavaScript 這位自由奔放、充滿創意的藝術家主導。他隨性、靈活,能快速揮灑出各種功能。但有時候...他實在太自由了,偶爾會把紅色顏料當成藍色(傳錯了變數型別),直到畫作展出(程式碼運行)時,我們才驚覺:「天啊!怎麼會這樣!」
今天,我們要為我們的團隊請來一位紀律嚴明的「架構師」—— TypeScript!
很多人一聽到要在現有專案引入 TypeScript,腦中就浮現「紅色錯誤海嘯」的恐怖畫面,感覺像是打開了潘朵拉的盒子。別怕!這很正常。今天的任務,就是給你一份「無痛升級作戰手冊」,一步步帶你從 JavaScript 自由派,平穩過渡到 TypeScript 紀律部隊,為你的程式碼加上「品質保證」!
在開始動手前,我們先來點心理建設。為什麼要放棄自由,擁抱紀律?
錯誤的「先知」:TS 就像一個有預知能力的夥伴,在你的程式碼還沒跑起來之前,它就會拍拍你的肩膀說:「嘿,老兄,你這裡不小心把數字傳給一個需要字串的函式了,趕快改一下。」這能消滅掉無數個可能在半夜把你叫醒的 Bug。
會讀心術的 IDE:當你用上 TS,你的 VS Code 就像吃了大還丹,功力大增。它能精準地提示你物件有哪些屬性、函式該傳什麼參數,自動補全功能變得無比絲滑,寫起程式碼來行雲流水。
團隊合作的「共同語言」:TS 的型別定義就是一份活的、不會說謊的「技術文件」。隊友一看就知道你的組件需要什麼 props
,你的函式回傳什麼資料,大大減少了溝通成本和誤解。
假設你手上有一個用 Vite 建立的純 JS 的 Vue 3 專案。別擔心,我們一步步來。
首先,我們需要安裝 TypeScript 編譯器和一個專門「翻譯」Vue 檔案給 TS 聽的工具 vue-tsc
。
# 使用 npm
npm install -D typescript vue-tsc
# 或使用 yarn
yarn add -D typescript vue-tsc
typescript
: TS 的核心編譯器,我們的大腦。vue-tsc
: 專門用來檢查 .vue
檔案的工具,是我們的「Vue 專家顧問」。tsconfig.json
)在專案根目錄下建立一個 tsconfig.json
檔案。這是 TS 的「作戰計畫書」,告訴它該如何工作。
先別急著追求完美! 我們的首要目標是「讓專案先能跑起來」,而不是立刻解決所有問題。所以,我們先用一個比較寬鬆的「急救設定」:
// tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"strict": false, // 先關掉嚴格模式,給自己一點喘息空間!
"noImplicitAny": false, // 允許隱性的 any 型別,暫時忽略一些警告
"skipLibCheck": true, // 跳過對 node_modules 裡宣告檔案的檢查,加速編譯
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": ["vite/client"], // 如果你用 Vite
"paths": {
"@/*": ["src/*"] // 讓 TS 看得懂 @/ 這種路徑別名
},
"lib": ["ESNext", "DOM", "DOM.Iterable"]
},
// 告訴 TS 該檢查哪些檔案
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
// 如果你的專案有 tsconfig.node.json,就加上這個引用
"references": [{ "path": "./tsconfig.node.json" }]
}
重點:
strict: false
和noImplicitAny: false
是我們暫時的「和平協議」。這能讓你在遷移初期,不會被成千上萬的錯誤淹沒。我們的策略是:先求有,再求好。
好了,深呼吸。現在,把你的 main.js
改名為 main.ts
,然後隨便找一個 .vue
檔案,把 <script setup>
改成 <script setup lang="ts">
。
然後執行 npm run dev
... 砰!你的終端機可能就「炸」了,一片紅。別慌,這是正常的!我們來一個個拆解。
Cannot find module './components/MyButton.vue'. ts(2307)
這是最常見的錯誤。因為 TS 天生不認識 .vue
檔案是什麼碗糕。你需要手動「教」它。
解決方案:在你的 src
資料夾下,建立一個 env.d.ts
或 vue-shims.d.ts
檔案,貼上以下程式碼:
// src/env.d.ts
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
這段程式碼等於是告訴 TS:「嘿,以後看到 .vue
結尾的檔案,你就把它當成一個 Vue 組件來處理,別再大驚小怪了!」
Could not find a declaration file for module 'some-library'.
當你引入一個純 JS 的第三方函式庫時,TS 會抱怨說:「我不知道這個函式庫的『說明書』(型別定義檔)在哪。」
解決方案:
npm
查一下,通常這個函式庫的型別定義會以 @types/
開頭。例如,如果你用了 lodash
,就執行 npm install -D @types/lodash
。env.d.ts
,在裡面加一行:
declare module 'some-library';
這等於是跟 TS 說:「好了好了,我知道了,你先別管 some-library
這個東西,相信我就對了。」這能暫時解決問題,讓專案跑起來。當你的專案終於能再次成功運行時,恭喜你,最難的一步已經過去了!
現在,不要貪心。一次只專心修改一個組件。
.vue
檔案,加上 lang="ts"
。ref
, reactive
加上型別。當你對 TS 越來越有信心時,就可以回到 tsconfig.json
,把 noImplicitAny
改回 true
,最終目標是開啟 strict: true
,享受最嚴格的保護!
Vue 3 為了讓我們能愉快地使用 TS,提供了一些專用武器:
ref<T>()
: 你可以明確告訴 ref
它要保管什麼型別的資料,例如 const name = ref<string>('Alice');
。defineProps<T>()
: 這是 Composition API 的一大亮點!你可以用 interface
或 type
來定義 props
的型別,超級清晰!defineEmits<T>()
: 同樣地,你也可以為 emits
定義型別,告訴大家這個組件會發出哪些事件。這些我們在接下來的章節會詳細介紹,它們會讓你的 Vue + TS 開發體驗更上一層樓!
lang="ts"
並修復所有型別錯誤。今天我們進行了一場「專案升級作戰」。記住,從 JS 遷移到 TS 的關鍵在於循序漸進。不要指望一蹴可幾。先用寬鬆的設定讓專案「活下來」,然後再逐步、分批地收緊規則,清理錯誤。這個過程就像是整理一個雜亂的房間,一次整理一個角落,最終你會得到一個乾淨、整潔、令人安心的空間。
本日關鍵字回顧
tsconfig.json
: TS 的設定檔,我們的作戰計畫書。vue-tsc
: 專門檢查 Vue 檔案的 TS 工具。declare module
: 用來「教」TS 認識它不認識的模組,如 .vue
檔案。strict: true
: 我們追求的終極「嚴格模式」。恭喜你完成了這次艱鉅但回報豐厚的升級!明天,我們將深入學習如何在 Vue 中使用 TS 的超強武器:型別化的 Props 與 Emits!