对象可能为“空”。在 ref(null) 上
Posted
技术标签:
【中文标题】对象可能为“空”。在 ref(null) 上【英文标题】:Object is possibly 'null'. on a ref(null) 【发布时间】:2021-03-09 13:58:18 【问题描述】:从我找到的文档中学习 Vue Composition API(和 TypeScript),我应该使用 ref(null)
来供我在 <template>...</template>
中的子组件使用。
这个子组件有open()
之类的方法,我是这样访问它的:
setup()
const subcomponentRef= ref(null);
subcomponentRef.value.open();
return subcomponentRef ;
我同意这可能会显示错误Object is possibly 'null'.
指向subcomponentRef.value
,但奇怪的是即使我添加了条件if (subcomponentRef !== null && subcomponentRef.value !== null) ...
,它仍然显示该错误。 为什么?
还尝试像subcomponentRef?.value?.open()
一样访问它,但我收到此错误Property 'open' does not exist on type 'never'.
。
还尝试添加 非空断言,例如 confirmation.value!.open();
并收到相同的错误 Property 'open' does not exist on type 'never'.
。
知道这里有什么问题吗?或者我应该用实际组件预定义它而不是使用ref(null)
?但我不知道如何正确地做到这一点,在文档中找不到。
【问题讨论】:
您好像在引用一个组件,请分享您是如何导入它的 我正在使用 NuxtJS 及其自动注册组件的组件模块,但可以说我不使用它,我会像import subcomponent from './subcomponent.vue';
和模板 <subcomponent ref="subcomponentRef" />
那样使用它跨度>
【参考方案1】:
尝试any
,如果没有任何效果!
setup()
const buttonRef= ref<any>(null); // <-- highlight
const buttonClicked = () => buttonRef.value.clicked = true
return buttonClicked, buttonRef
【讨论】:
【参考方案2】:如果您在这里使用 Typescript 在 vue 组合 API 中声明可为空的数字引用,
setup()
const foo = ref<number | null>(null);
const someAction = () =>
foo.value = 1
return foo, someAction ;
在上面的代码sn-p上,
您可以更改 number
数据类型以匹配您所需的数据类型。
此外,如果需要,您可以使用 |
运算符添加多种可能的数据类型。
【讨论】:
【参考方案3】:您的基本问题是您没有输入 ref。如果 ref 不仅具有您最初使用的类型,您总是需要向 ref 添加一个类型。
假设您的组件是 MySubcomponent,您需要向 ref 添加一个类型
// In this case, you need to type
const subcomponentRef = ref<ComponentPublicInstance<typeof MySubcomponent> | null>(null);
// In this case not, type is inferred to Ref<number>
const myRef = ref(15)
然后您可以使用您的 if 并访问其中的组件实例的方法。请注意,您只能在设置完成后访问它,例如在事件监听器中,挂载的钩子,......
【讨论】:
【参考方案4】:这应该很简单,你只需告诉 TS 它实际上不是空的,使用 non-null assertion operator:
setup()
const foo = ref(null);
onMounted(() =>
foo!.someMethod();
return foo ;
【讨论】:
只有在您的类型为 null | 时才有效其他类型。在这种情况下,类型为空。所以一会儿!告诉 typescript 它可能不为 null,TS 仍然没有关于实际类型的类型信息,并且会抱怨缺少 someMethod。【参考方案5】:感谢您对此的帮助。这是我使用 Typescript 在 Vue 3 Composition API 中聚焦输入元素的简化解决方案:
<template>
<input ref="inputField">
</template>
const inputField = ref(null)
inputField.value.focus() // ERROR: TS2531: Object is possibly 'null'
解决方案:
const inputField = ref<null | focus: () => null >(null)
if(inputField.value)
inputField.value.focus()
确保定义了一个焦点函数。
【讨论】:
【参考方案6】:您应该使用typeof yourComponent
或null
使用组件类型,然后使用?
可选链接来访问方法/属性:
setup()
const subcomponentRef= ref < typeof subcomponent| null > (null);
subcomponentRef.value?.open();
return subcomponentRef ;
【讨论】:
【参考方案7】:好问题!我和你有同样的问题,偶然发现了这个answer。对我有用的是定义对象的形状(打字稿界面),所以 TS 知道什么存在什么不存在。
将这些知识应用到您的示例中:
setup()
const subcomponentRef = ref(null)
subcomponentRef.value.open() // TS error here
变成:
setup()
const subcomponentRef = ref<null | open: () => null >(null)
subcomponentRef.value?.open()
TS 错误现在消失了,因为:
Typescript 知道函数open
可以在 subcomponentRef
上使用,因为我们预先 declared 它
使用optional chaining,当subcomponentRef.value
是null
或undefined
时,我们告诉Typescript 不要再往下看。
通常这些接口已经在某处提供,不需要手动创建。所以就我而言,我只需要使用来自quasar
的QInput
接口来避免resetValidation
的TS 错误不可用:
import QInput from 'quasar'
const driverIdInput = ref<QInput>()
driverIdInput.value?.resetValidation()
我希望这有助于澄清问题并避免这些令人讨厌的错误。
【讨论】:
以上是关于对象可能为“空”。在 ref(null) 上的主要内容,如果未能解决你的问题,请参考以下文章
打字稿:React Native useRef 给出错误“对象可能为空”
React Hooks 和 TypeScript Fetching API:对象可能为“空”
特例模式(Special Case Pattern)与空对象模式(Null Pointer Pattern)—— 返回特例对象而非 null