El objeto posiblemente sea 'nulo'. en una referencia (nulo)

Nov 26 2020

Aprendiendo la API de composición Vue (y TypeScript), de los documentos que encontré, debería usar ref(null)para usar un subcomponente que tengo dentro <template>...</template>.

Este subcomponente tiene métodos como open(), y estoy accediendo a él así:

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

Estoy de acuerdo puede mostrar el error Object is possibly 'null'.señalado subcomponentRef.value, pero lo extraño es que incluso si agregué una condición if (subcomponentRef !== null && subcomponentRef.value !== null) { ... }, todavía muestra ese error. ¿¿Por qué??

También intenté acceder a él como subcomponentRef?.value?.open()pero recibo este error Property 'open' does not exist on type 'never'..

También intenté agregar afirmaciones no nulas , me gusta confirmation.value!.open();y recibe el mismo error Property 'open' does not exist on type 'never'..

¿Alguna idea de lo que pasa aquí? ¿O tal vez en lugar de usar ref(null), debería predefinirlo con el componente real? pero no tengo idea de cómo hacerlo correctamente, no puedo encontrarlo en los documentos.

Respuestas

1 DarkLite1 Dec 02 2020 at 10:44

¡Gran pregunta! Tuve el mismo problema que tú y me encontré con esta respuesta . Lo que funcionó para mí fue definir la forma del objeto (una interfaz mecanografiada), por lo que TS sabe qué hay y qué no.

Aplicando este conocimiento a su ejemplo:

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

Se convierte en:

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

El error TS ahora desapareció porque:

  • Letra de imprenta conoce la función openestá disponible en subcomponentRefporque nos declaramos que por adelantado
  • Con el encadenamiento opcional le decimos a TypeScript que no busque más cuando subcomponentRef.valuees nullo undefined.

Por lo general, estas interfaces ya se proporcionan en algún lugar y no es necesario crearlas manualmente. Entonces, en mi caso, solo tuve que usar la QInputinterfaz de quasarpara evitar el error de TS de resetValidationno estar disponible:

import { QInput } from 'quasar'

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

Espero que esto ayude a aclarar las cosas y evitar estos desagradables errores.

BoussadjraBrahim Nov 26 2020 at 19:10

Debe usar el tipo de componente usando typeof yourComponento nullluego usar ?para acceder a métodos / propiedades:

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