普通网友 2025-10-28 23:35 采纳率: 98.4%
浏览 1
已采纳

Vue3 + TS 中如何正确声明 emits 类型?

在 Vue3 + TypeScript 项目中,使用 `<script></script>
  • 写回答

1条回答 默认 最新

  • 火星没有北极熊 2025-10-28 23:37
    关注

    1. 基础概念:Vue3 中的 <script> 与 TypeScript 集成

    在 Vue3 的单文件组件(SFC)中,<script setup> 是一种编译时语法糖,专为组合式 API 设计。结合 TypeScript 使用时,可通过类型推导增强开发体验。

    <script setup lang="ts">
    interface User {
      id: number
      name: string
    }
    
    const user: User = { id: 1, name: 'Alice' }
    </script>
    

    使用 lang="ts" 启用 TypeScript 编译支持,确保 IDE 提供智能提示和类型检查。

    2. 类型安全的数据定义与响应式处理

    <script setup> 中,利用 refreactive 定义响应式数据时,应显式标注类型以提升可维护性。

    函数用途TypeScript 支持方式
    ref<T>()创建可响应的基本类型泛型指定值类型
    reactive<T>()创建响应式对象接口或类型别名定义结构

    3. 组件 Props 的类型化声明

    通过 defineProps 宏配合 TypeScript 接口,实现类型安全的属性传递。

    <script setup lang="ts">
    interface Props {
      title: string
      count?: number
    }
    
    const props = defineProps<Props>()
    </script>
    

    该模式避免运行时类型错误,并支持默认值与必填校验。

    4. 使用泛型提升组件复用性

    在复杂业务场景中,可借助泛型使组件更具扩展性。

    • 定义泛型 props 接口
    • 结合 EmitsOptions 类型约束事件输出
    • 利用条件类型处理可选逻辑分支

    5. 自定义 Hook 的封装与类型推导

    将通用逻辑抽象为 Composable 函数,是 Vue3 + TypeScript 项目的最佳实践之一。

    // useFetch.ts
    import { ref } from 'vue'
    
    export function useFetch<T>(url: string) {
      const data = ref<T | null>(null)
      const error = ref<Error | null>(null)
    
      fetch(url)
        .then(res => res.json())
        .then(json => data.value = json as T)
        .catch(err => error.value = err)
    
      return { data, error }
    }
    

    6. 事件通信的类型安全机制

    使用 defineEmits 结合 TypeScript 联合类型,精确描述触发事件的参数结构。

    <script setup lang="ts">
    const emit = defineEmits<{
      (e: 'update', id: number): void
      (e: 'close'): void
    }>()
    
    emit('update', 123) // 类型正确
    // emit('update', 'abc') // 编译报错
    </script>
    

    7. 深层类型推导与交叉类型应用

    当组件接收多个 mixin 式配置时,可使用交叉类型(&)合并不同模块的类型定义。

    type UIConfig = { theme: string }
    type APIConfig = { endpoint: string }
    type FullConfig = UIConfig & APIConfig
    

    此方法适用于高阶组件或插件系统的设计。

    8. 构建流程中的 TypeScript 校验集成

    在项目构建阶段,通过 Vite 或 Webpack 插件启用 vue-tsc 进行类型检查。

    1. 安装 vue-tsc:npm install -D vue-tsc
    2. 添加 script 到 package.json:"check": "vue-tsc --noEmit"
    3. CI/CD 流程中执行类型检查
    4. 配合 ESLint 实现静态分析闭环

    9. 错误边界与异常类型的处理策略

    虽然 Vue3 尚未原生支持 Error Boundaries,但可通过 try/catch 包裹 setup 逻辑并结合 Sentry 等工具上报。

    try {
      const result = await apiCall<UserData>('/user')
    } catch (err: unknown) {
      if (err instanceof Error) {
        console.error(err.message)
      }
    }
    

    10. 可视化流程:组件初始化与类型解析生命周期

    graph TD A[Parse SFC] --> B{Has <script setup lang="ts">?} B -- Yes --> C[Transform via compiler-sfc] C --> D[Extract Types and Macros] D --> E[Type Check with vue-tsc] E --> F[Emit JavaScript & Declaration Files] F --> G[Bundle with Vite/Webpack]

    该流程展示了从源码到产物过程中 TypeScript 如何参与编译链路。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月29日
  • 创建了问题 10月28日