使用volar验证TS useClickOutside参数类型错误
来源:4-11 useClickOutside 第一个自定义函数
辰辰ollie
2021-08-24
//Dropdown.vue
const dropdownRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(dropdownRef)
//...其他代码
//useClickOutside.ts
const useClickOutside = (elementRef: Ref<null | HTMLElement>): Ref<boolean> => {
const isClickOutside = ref(false)
const handler = (e: MouseEvent) => {
if (elementRef.value) {
if (elementRef.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false
} else {
isClickOutside.value = true
}
}
}
onMounted(() => {
document.addEventListener('click', handler)
})
onUnmounted(() => {
document.removeEventListener('click', handler)
})
return isClickOutside
}
老师你好:
项目中使用了volar来做ts效验,原来使用vetur是没问题的,换成volar后类型出现以下错误,如图
尤雨溪已经说了未来volar会替代vetur成为新的工具,所以麻烦老师可以帮忙看看怎么解决。
项目地址:https://github.com/ollieSk8/zhihu-project
写回答
2回答
-
同学你好 看了一下 这里我认为 volar 的实现有可能有点问题 它会将 HTMLElement 类型直接展开,造成类型的不匹配,暂时解决这个问题,可以使用 any 大法,或者去掉泛型让它推论成 null 类型,都可以。
const dropdownRef = ref(null) const dropdownRef = ref<any>(null)
022021-08-25 -
张轩
2021-08-25
同学 给你提issue 精神赞一个,非常好。我要好好宣扬一下,他回答就是说这个错误和 volar 没关系。
我今天又仔细看了一下,应该是 vue 的定义文件升级有关系。
export declare function ref<T>(value: T): Ref<UnwrapRef<T>>;
当调用 ref 有值的时候会将 T 类型自动展开,这样就会造成不匹配,假如你不想用上个回答的 any 大法。可以这样改,将 useClickOutside 的接受的参数也展开,让他两匹配即可。
// useClickOutside 把 UnwrapRef 引进来 import { ref, onMounted, onUnmounted, Ref, UnwrapRef } from 'vue' 参数定义为 UnwrapRef 类型 const useClickOutside = (elementRef: Ref<null | UnwrapRef<HTMLElement>>)
这样就没有错误了,当然这样只是为了类型通过,也比较繁琐,建议还是直接 any 或者 不加泛型,要让ts 为我们服务,不要追求极致。
012021-08-25
相似问题