对象可能为“空”。在 ref(null) 上

rmo*_*lva 8 typescript vue.js vuejs3 vue-composition-api

学习Vue公司组成的API(和打字稿),从我发现的文档,我应该使用ref(null)一个子组件我有内部使用<template>...</template>

这个子组件有像这样的方法open(),我像这样访问它:

setup() {
    const subcomponentRef= ref(null);
    subcomponentRef.value.open();
    return { subcomponentRef };
}
Run Code Online (Sandbox Code Playgroud)

我同意这可能会显示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),我应该使用实际组件预定义它而不是使用?但我不知道如何正确地做到这一点,在文档中找不到。

Dar*_*te1 14

好问题!我和你有同样的问题并偶然发现了这个答案。对我有用的是定义对象的形状(打字稿界面),这样 TS 就知道存在什么、不存在什么。

将这些知识应用到您的示例中:

setup() {
    const subcomponentRef = ref(null)
    subcomponentRef.value.open() // TS error here
}
Run Code Online (Sandbox Code Playgroud)

变成:

setup() {
    const subcomponentRef = ref<null | { open: () => null }>(null)
    subcomponentRef.value?.open()
}
Run Code Online (Sandbox Code Playgroud)

TS 错误现已消失,因为:

  • Typescript 知道该函数open可用,subcomponentRef因为我们预先声明了它
  • 通过可选链接,subcomponentRef.value我们告诉 Typescript 在isnull或 时不要进一步查看undefined

通常这些接口已经在某处提供,不需要手动创建。因此,就我而言,我只需使用QInput接口来quasar避免 TSresetValidation不可用的错误:

import { QInput } from 'quasar'

const driverIdInput = ref<QInput>()
driverIdInput.value?.resetValidation()
Run Code Online (Sandbox Code Playgroud)

我希望这有助于澄清问题并避免这些令人讨厌的错误。


Bou*_*him 2

您应该使用组件类型typeof yourComponentnull然后使用?可选链接来访问方法/属性:

setup() {
    const subcomponentRef= ref < typeof subcomponent| null > (null);
    subcomponentRef.value?.open();
    return { subcomponentRef };
}
Run Code Online (Sandbox Code Playgroud)