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
相关产品推荐
相关产品推荐

