You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3自定义hook用reactive时UnwrapRefSimple<T>无法赋值给T如何解决

错误原因

Vue3的reactive API会自动对传入的值做响应式解包,你用reactive([...items])创建的options数组,内部元素的类型会被TS推导为UnwrapRefSimple<T>,和selectItem要求的T类型不兼容,因此触发类型错误。

解决方案

以下三种方案均可解决问题,可根据使用场景选择:

  • 方案1:改用ref存储选项数组(推荐)
    避免reactive的自动解包逻辑改变元素类型,同时优化select函数的参数类型,提升类型安全性:

    import { ref, Ref } from 'vue'
    
    const useSelectArray = <T>(items: T[]) => {
      const selectItem: Ref<T|null> = ref(null)
      // 改用ref存储数组,元素类型保持为T
      const options = ref([...items])
      // 优化参数类型,避免传入不存在的属性
      const select = (key: keyof T, value: T[typeof key]) => {
        const trigger = options.value.find((item: T) => item[key] === value)
        if (trigger) {
          selectItem.value = trigger
        }
      }
    
      return {  
        selectItem,
        select,
        items: options
      }
    }
    
  • 方案2:强制指定reactive的类型
    如果你一定要用reactive存储数组,可以显式声明数组类型,覆盖默认的解包推导逻辑:

    // 显式指定options的类型为T[]
    const options = reactive<T[]>([...items])
    
  • 方案3:对赋值的值做类型断言
    适合临时修复场景,仅需修改赋值行即可:

    selectItem.value = trigger as T
    

额外优化建议

原代码中select函数的key参数声明为string类型,无法校验传入的属性是否真的存在于T类型中,改为keyof T可在编译阶段提前捕获属性名拼写错误等问题。


内容的提问来源于stack exchange,提问作者xuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:24:01