第十二章: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 提供了完美的类型安全开发体验:
- 零配置开箱即用
- 完善的类型声明支持
- 路径映射和组件类型推导
- 构建时类型检查
- 库模式类型产物生成