如何在TypeScript环境的Composition API中正确声明静态ref?
问题根源
你没有给ref显式声明类型,当初始值为null时,TS会默认将该ref的类型推断为Ref<null>:
- 直接调用
searchRef.value.focus()时,TS检测到value可能为null,抛出TS2531错误 - 使用可选链
searchRef.value?.focus()时,TS认为value除了null外没有其他可能的类型,因此可选链后的类型为never,抛出找不到focus属性的TS2339错误
正确解决方案
方案1:给ref添加泛型类型(最推荐)
根据你绑定的DOM元素/组件类型,给ref指定对应的泛型即可,以绑定原生input输入框为例:
import { ref, onMounted } from 'vue' // 声明ref的类型为 「HTMLInputElement」或「null」 const searchRef = ref<HTMLInputElement | null>(null) onMounted(() => { // 此时可选链可正常识别类型,无报错 searchRef.value?.focus() })
不同场景的泛型选择:
- 绑定原生DOM元素:对应元素的内置类型,例如
<div>对应HTMLDivElement、<button>对应HTMLButtonElement - 绑定自定义Vue组件:使用
InstanceType<typeof 组件名>作为泛型,示例:
import Search from './Search.vue' const searchRef = ref<InstanceType<typeof Search> | null>(null)
方案2:使用非空断言
如果你确定onMounted执行时模板已经完成渲染,ref一定已经绑定到对应元素,也可以直接用非空断言!告诉TS该值一定不为null:
const searchRef = ref<HTMLInputElement | null>(null) onMounted(() => { searchRef.value!.focus() })
注意:该方式需要你自行保证ref赋值的时机正确性,避免运行时报错。
内容的提问来源于stack exchange,提问作者WoJ
相关产品推荐
相关产品推荐

