O objeto é possivelmente 'nulo'. em um ref (nulo)

Nov 26 2020

Aprendendo Vue Composition API (e TypeScript), a partir dos documentos que encontrei, devo usar ref(null)para usar por um subcomponente que tenho dentro <template>...</template>.

Este subcomponente tem métodos como open(), e eu estou acessando assim:

setup() {
    const subcomponentRef= ref(null);
    subcomponentRef.value.open();
    return { subcomponentRef };
}

Isso eu concordo pode mostrar o erro Object is possibly 'null'.apontado subcomponentRef.value, mas o estranho é que mesmo se eu adicionei uma condição if (subcomponentRef !== null && subcomponentRef.value !== null) { ... }, ainda mostra esse erro. Por quê??

Também tentei acessá-lo como subcomponentRef?.value?.open()mas recebo este erro Property 'open' does not exist on type 'never'..

Também tentei adicionar asserções não nulas , como confirmation.value!.open();e recebe o mesmo erro Property 'open' does not exist on type 'never'..

Alguma ideia do que está errado aqui? ou talvez em vez de usar ref(null), devo predefini-lo com o componente real? mas não tenho ideia de como fazer isso corretamente, não consigo encontrar nos docs.

Respostas

1 DarkLite1 Dec 02 2020 at 10:44

Ótima pergunta! Eu tive o mesmo problema que você e me deparei com esta resposta . O que funcionou para mim foi definir a forma do objeto (uma interface datilografada), então TS sabe o que está lá e o que não está.

Aplicando esse conhecimento ao seu exemplo:

setup() {
    const subcomponentRef = ref(null)
    subcomponentRef.value.open() // TS error here
}

Torna-se:

setup() {
    const subcomponentRef = ref<null | { open: () => null }>(null)
    subcomponentRef.value?.open()
}

O erro de TS agora desapareceu porque:

  • O typescript sabe que a função openestá disponível subcomponentRefporque a declaramos antecipadamente
  • Com o encadeamento opcional , dizemos ao Typescript para não procurar mais quando subcomponentRef.valueé nullou undefined.

Normalmente, essas interfaces já são fornecidas em algum lugar e não precisam ser criadas manualmente. Portanto, no meu caso, apenas tive que usar a QInputinterface de quasarpara evitar o erro do TS de resetValidationnão estar disponível:

import { QInput } from 'quasar'

const driverIdInput = ref<QInput>()
driverIdInput.value?.resetValidation()

Espero que isso ajude a esclarecer as coisas e evitar esses erros desagradáveis.

BoussadjraBrahim Nov 26 2020 at 19:10

Você deve usar o tipo de componente usando typeof yourComponentou nullentão usar ?para acessar métodos / propriedades:

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