第十二章: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 提供了完美的类型安全开发体验:

  • 零配置开箱即用
  • 完善的类型声明支持
  • 路径映射和组件类型推导
  • 构建时类型检查
  • 库模式类型产物生成
相关推荐
Dlrb1211几秒前
C语言-字符串指针与函数指针
java·c语言·前端
PBitW5 分钟前
组件封装注意事项
前端·vue.js
weiggle11 分钟前
Android 输入事件分发流程:从物理触控到 Activity 的完整旅程
前端
yingyima14 分钟前
开发者必备在线工具集合 2025:实战案例解析
前端
前端毕业班16 分钟前
面试官:实现一个带类型约束的 EventEmitter
前端·面试
卷帘依旧19 分钟前
SPA 中的 Hash 和 History 模式
前端
用户44455436542622 分钟前
AndroidAutoSize使用时遇到的特麻烦bug
前端
茉莉玫瑰花茶26 分钟前
LangGraph 入门教程:构建 AI 工作流 [ 案例三 ]
前端·人工智能·python
scan72430 分钟前
pydantic格式输出
服务器·前端·javascript
ZC跨境爬虫37 分钟前
跟着MDN学HTML_day44:(ProcessingInstruction接口)
前端·javascript·ui·html·媒体