第一章:Vue与TypeScript初识

为什么选择TypeScript

说实话,我刚开始用Vue的时候,也是纯JavaScript一把梭。直到有一次,我接手了一个中型项目,光找类型错误就花了两天。嗯,从那以后,我就决定在Vue项目里全面引入TypeScript。

TypeScript能给你带来什么?说白了,就是类型安全。你想想看,JavaScript是动态类型,变量可以随时变成任何类型。这在小型项目里还好,一旦项目超过5万行代码,光靠人脑记住所有类型,几乎不可能。

核心价值:TypeScript在编译阶段就能捕获类型错误,而不是等到运行时才发现。我个人认为,这是它最大的价值所在。

我在项目中遇到过这样一个场景:一个接口返回的数据结构变了,前端没有及时更新类型定义,结果页面直接白屏。如果用了TypeScript,这种问题在编译时就会被发现。

TypeScript vs JavaScript:一个直观对比

特性 JavaScript TypeScript
类型系统 动态类型 静态类型
错误发现时机 运行时 编译时
IDE支持 基础提示 智能提示、自动补全
重构能力 手动查找替换 安全重构
学习成本 中等

我的建议:如果你正在开发一个长期维护的项目,或者团队人数超过3人,直接上TypeScript。短期看多花了点时间写类型,长期看省下的调试时间绝对值得。

Vue3 + TS 项目初始化

好,我们直接动手。创建一个Vue3 + TypeScript项目,我推荐用Vite。为什么?因为它快,真的快。

# 使用npm创建项目
npm create vite@latest my-vue-ts-app -- --template vue-ts

# 或者用yarn
yarn create vite my-vue-ts-app --template vue-ts

# 进入项目目录
cd my-vue-ts-app

# 安装依赖
npm install

创建完成后,你会看到这样的项目结构。我来逐个解释每个文件的作用。

项目结构解析

my-vue-ts-app/
├── index.html          # 入口HTML文件
├── package.json        # 项目配置和依赖
├── tsconfig.json       # TypeScript配置文件
├── vite.config.ts      # Vite构建配置
├── env.d.ts            # 环境类型声明
├── src/
│   ├── main.ts         # 应用入口文件
│   ├── App.vue         # 根组件
│   ├── components/     # 组件目录
│   ├── assets/         # 静态资源
│   └── style.css       # 全局样式
└── public/             # 公共资源

关键文件详解

tsconfig.json — 这是TypeScript的核心配置。我习惯这样配置:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,
    "noEmit": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

注意:我曾经因为忘了配置 paths 别名,导致项目里到处都是 ../../../components 这种路径。后来重构时改配置,花了整整一天。所以一开始就把路径别名配好,省心。

env.d.ts — 这个文件用来声明Vue单文件组件的类型。没有它,TypeScript不认识 .vue 文件。

/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

vite.config.ts — Vite的配置文件,用TypeScript写,天然支持类型提示。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
})

第一个TypeScript组件

我们来写一个简单的计数器组件,感受一下TypeScript在Vue中的用法。

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

// 显式声明类型
const count = ref<number>(0)

// 带类型的函数
function increment(): void {
  count.value++
}

// 带参数和返回类型的函数
function add(amount: number): number {
  count.value += amount
  return count.value
}
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">+1</button>
    <button @click="add(5)">+5</button>
  </div>
</template>

小技巧:<script setup> 里加上 lang="ts",Vue就会自动启用TypeScript支持。你写 ref<number>(0) 时,IDE会给你完整的类型提示。

避坑指南

我曾经犯过一个低级错误:在 script setup 里忘了加 lang="ts",结果写了半天类型注解,IDE一点反应都没有。后来检查才发现,Vue默认是JavaScript模式。

还有一次,我在 tsconfig.json 里把 strict 设成了 false,想着先跑起来再说。结果项目越写越大,类型错误越来越多,最后不得不花一周时间补类型。所以我的建议是:从一开始就开启严格模式

小结

这一章我们聊了为什么选择TypeScript,怎么初始化一个Vue3 + TS项目,以及项目里每个文件是干什么的。你想想看,有了类型系统,你的代码就像有了说明书,别人接手你的项目时,光看类型定义就能理解七八分。

下一章,我们会深入Vue3的Composition API,看看TypeScript如何与 refreactivecomputed 这些核心API完美配合。到时候我会分享一些我在实际项目中踩过的坑,保证让你少走弯路。