# Vue TypeScript 模式 Vue 3 开发的 TypeScript 专属模式。 ## Provide/Inject 类型 使用 `InjectionKey` 实现类型安全的依赖注入: ```ts import type { InjectionKey } from 'vue' import type { User } from './types' // 定义类型化的 key export const UserKey: InjectionKey = Symbol('user') // 提供者组件 const user = ref({ id: 1, name: 'John' }) provide(UserKey, user) // 消费者组件 const user = inject(UserKey) // Ref | undefined const user = inject(UserKey)! // Ref(断言非空) ``` **使用默认值:** ```ts const user = inject(UserKey, ref({ id: 0, name: 'Guest' })) // 类型:Ref(无 undefined) ``` ## vue-tsc 严格模板 启用更严格的模板类型检查: ```bash # 以严格模式检查模板 vue-tsc --noEmit --strict-templates ``` 可捕获如下模板错误: - 访问不存在的属性 - 错误的 prop 类型 - 缺少必需的 props ## tsconfig 设置 **Vue 3 必需项:** ```json { "compilerOptions": { "moduleResolution": "bundler", "verbatimModuleSyntax": true, "strict": true, "jsx": "preserve" } } ``` **`moduleResolution: "bundler"`** - 与 Vite/webpack 的解析方式匹配。避免 `.js` 扩展名问题。 **`verbatimModuleSyntax: true`** - 强制使用显式 `type` 导入: ```ts // ❌ 可能导致打包工具出现问题 import { User } from './types' // ✅ 显式类型导入 import type { User } from './types' ``` ## 组件类型辅助工具 **从组件中提取 props 类型:** ```ts import type { ComponentProps, ComponentSlots, ComponentEmits } from 'vue-component-type-helpers' import MyComponent from './MyComponent.vue' type Props = ComponentProps type Slots = ComponentSlots type Emits = ComponentEmits ``` **提取暴露的方法:** ```ts import type { ComponentExposed } from 'vue-component-type-helpers' type Exposed = ComponentExposed ``` ## 泛型组件 使用类型化的 slots 定义泛型组件: ```vue ``` ## Ref 类型收窄 正确处理 ref 类型收窄: ```ts const maybeUser = ref(null) // ❌ TypeScript 仍然视为 User | null if (maybeUser.value) { maybeUser.value.name // 错误:可能为 null } // ✅ 使用 computed 或提取值 const userName = computed(() => maybeUser.value?.name ?? 'Guest') // ✅ 或在同一表达式中守卫 maybeUser.value && maybeUser.value.name ``` ## 事件处理器类型 正确为事件处理器添加类型: ```ts // DOM 事件 const onClick = (e: MouseEvent) => { ... } const onInput = (e: Event) => { const target = e.target as HTMLInputElement console.log(target.value) } // 组件 emits const onUpdate = (value: string) => { ... } ``` ## 常见错误 **忘记显式导入类型:** ```ts // ❌ 运行时导入本应是纯类型的内容 import { User } from './types' // ✅ 纯类型导入 import type { User } from './types' ``` **未对字面量类型使用 `as const`:** ```ts // ❌ 类型为 string[] const variants = ['primary', 'secondary'] // ✅ 类型为 readonly ['primary', 'secondary'] const variants = ['primary', 'secondary'] as const ```