第十二章:TypeScript 深度集成

第十二章:TypeScript 深度集成

12.1 Vite + TypeScript 基础

开箱即用

Vite 原生支持 TypeScript,无需额外配置:

bash 复制代码
npm create vite@latest my-app -- --template vue-ts
# 或 react-ts

工作原理

  • 使用 esbuild 编译 TypeScript
  • 仅转换,不进行类型检查
  • 开发环境极速,构建时可通过插件检查

12.2 tsconfig.json 最佳配置

基础配置

json 复制代码
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "jsx": "preserve",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "allowImportingTsExtensions": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
  "exclude": ["node_modules", "dist"]
}

路径映射

json 复制代码
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@utils/*": ["./src/utils/*"]
    }
  }
}

同时需要在 Vite 中配置:

javascript 复制代码
resolve: {
  alias: {
    '@': '/src',
    '@components': '/src/components',
    '@utils': '/src/utils'
  }
}

12.3 类型声明文件

环境变量类型

typescript 复制代码
// src/vite-env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string
  readonly VITE_APP_TITLE: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

模块类型声明

typescript 复制代码
// src/shims-vue.d.ts
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

// 声明图片模块
declare module '*.svg' {
  const src: string
  export default src
}

// 声明 CSS 模块
declare module '*.module.css' {
  const classes: { [key: string]: string }
  export default classes
}

12.4 组件类型推导

Vue 组件类型

vue 复制代码
<script setup lang="ts">
// 定义 Props 类型
interface Props {
  title: string
  count?: number
  items: string[]
}

const props = withDefaults(defineProps<Props>(), {
  count: 0
})

// 定义 Emits 类型
const emit = defineEmits<{
  (e: 'update', value: string): void
  (e: 'delete', id: number): void
}>()

// 定义 Slots 类型
defineSlots<{
  default(props: { item: string }): any
  header(): any
}>()
</script>

React 组件类型

tsx 复制代码
import { FC } from 'react'

interface ButtonProps {
  onClick?: () => void
  children: React.ReactNode
  variant?: 'primary' | 'secondary'
}

const Button: FC<ButtonProps> = ({ onClick, children, variant = 'primary' }) => {
  return (
    <button onClick={onClick} className={`btn btn-${variant}`}>
      {children}
    </button>
  )
}

12.5 类型检查工具

使用 vite-plugin-checker

bash 复制代码
npm install -D vite-plugin-checker
javascript 复制代码
import checker from 'vite-plugin-checker'

export default defineConfig({
  plugins: [
    checker({
      typescript: true,
      vueTsc: true,
      eslint: {
        lintCommand: 'eslint "./src/**/*.{ts,tsx,vue}"'
      }
    })
  ]
})

单独运行类型检查

json 复制代码
{
  "scripts": {
    "type-check": "tsc --noEmit",
    "build": "npm run type-check && vite build"
  }
}

12.6 高级类型技巧

动态导入类型

typescript 复制代码
// 获取导入模块的类型
const MyComponent = () => import('./MyComponent.vue')
type MyComponentType = Awaited<typeof MyComponent>

// 泛型组件
function useList<T extends { id: number }>(items: T[]) {
  const findById = (id: number): T | undefined => {
    return items.find(item => item.id === id)
  }
  return { findById }
}

工具类型使用

typescript 复制代码
// Partial、Required、Pick 等
interface User {
  id: number
  name: string
  email: string
  age?: number
}

type UserUpdate = Partial<User>
type UserBasic = Pick<User, 'id' | 'name'>

// 条件类型
type IsArray<T> = T extends any[] ? true : false
type A = IsArray<string[]> // true
type B = IsArray<string>   // false

12.7 构建类型产物

库模式类型声明

javascript 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import dts from 'vite-plugin-dts'

export default defineConfig({
  plugins: [
    dts({
      insertTypesEntry: true,
      rollupTypes: true
    })
  ],
  build: {
    lib: {
      entry: 'src/index.ts',
      formats: ['es', 'cjs']
    }
  }
})

package.json 配置

json 复制代码
{
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    }
  }
}

12.8 常见类型问题

问题 1:找不到模块

typescript 复制代码
// 添加类型声明
declare module 'my-module' {
  export function doSomething(): void
}

问题 2:全局类型扩展

typescript 复制代码
// global.d.ts
export {}

declare global {
  interface Window {
    myGlobalVar: string
  }
}

问题 3:第三方库类型缺失

bash 复制代码
# 安装 @types 包
npm install -D @types/lodash

# 或创建自定义声明
declare module 'untyped-lib'

本章小结

TypeScript + Vite 提供了完美的类型安全开发体验:

  • 零配置开箱即用
  • 完善的类型声明支持
  • 路径映射和组件类型推导
  • 构建时类型检查
  • 库模式类型产物生成
相关推荐
一袋米扛几楼981 天前
【网络安全】SIEM -Security Information and Event Management 工具是什么?
前端·安全·web安全
小陈工1 天前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python
Cobyte1 天前
3.响应式系统基础:从发布订阅模式的角度理解 Vue2 的数据响应式原理
前端·javascript·vue.js
竹林8181 天前
从零到一:在React前端中集成The Graph查询Uniswap V3池数据实战
前端·javascript
Mintopia1 天前
别再迷信"优化":大多数性能问题根本不在代码里
前端
倾颜1 天前
接入 MCP,不一定要先平台化:一次 AI Runtime 的实战取舍
前端·后端·mcp
军军君011 天前
Three.js基础功能学习十八:智能黑板实现实例五
前端·javascript·vue.js·3d·typescript·前端框架·threejs
恋猫de小郭1 天前
Android 上为什么主题字体对 Flutter 不生效,对 Compose 生效?Flutter 中文字体问题修复
android·前端·flutter
Moment1 天前
AI全栈入门指南:一文搞清楚NestJs 中的 Controller 和路由
前端·javascript·后端
禅思院1 天前
前端架构演进:基于AST的常量模块自动化迁移实践
前端·vue.js·前端框架