Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

268
Vistas
Error de mecanografiado cuando se utilizan varios tipos opcionales

Este es un ejemplo del error:

 interface Block { id: string; } interface TitleBlock extends Block { data: { text: "hi", icon: "hi-icon" } } interface SubtitleBlock extends Block { data: { text: "goodbye", } } interface CommentBlock extends Block { author: string; } type BlockTypes = TitleBlock | SubtitleBlock | CommentBlock function mapper(block : BlockTypes) { if(block?.data?.text){ // TS Error here!!! /** do something */ } }

ejemplo en vivo

Quiero hacer algo en la función cuando el bloque tiene un atributo específico pero TS no me permite hacerlo incluso cuando hay tipos en BlockTypes que tienen esa propiedad.

¿Cuál es la mejor forma de gestionar este tipo de funcionalidades?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

El operador de encadenamiento opcional ( ?. ) solo protege contra null e undefined ; no filtra una expresión de tipo unión a aquellos miembros que se sabe que contienen esa clave. Consulte este comentario en Microsoft/TypeScript#33736 para obtener una respuesta canónica.


El problema es que los tipos de objetos en TypeScript están abiertos y pueden contener más propiedades de las que conoce el compilador. Entonces, si block.data es veraz, desafortunadamente no implica que block.data.text exista:

 const oof = { id: "x", author: "weirdo", data: 123 } mapper(oof); // accepted

Aquí oof es un CommentBlock válido, por lo que se permite mapper(oof) , y oof.data es veraz, pero oof.data.text no está undefined , y tendrá un problema si intenta tratarlo como una string .

Por lo tanto, sería incorrecto (es decir, no sería seguro escribir) permitir el encadenamiento opcional para filtrar las uniones de la manera que desee.


La solución aquí, si no cree que los casos tipo oof son probables, es usar el operador in como protección de tipo :

 function mapper(block: BlockTypes) { if ("data" in block) { block.data.text.toUpperCase() } }

Esto funciona bien sin error del compilador. Por supuesto, todavía no es sólido exactamente de la misma manera que estrechar con ?. sería... si llama a mapper(oof) no hay errores del compilador pero obtendrá un error de tiempo de ejecución. Así que debes tener cuidado.

Es un poco extraño que TypeScript permita que se comporte in esta manera pero no permita otras construcciones similares. Puede leer la discusión en microsoft/TypeScript#10485 para ver por qué sucedió eso. En general, parece ser que cuando las personas escriben "foo" in bar , rara vez hacen algo incorrecto, pero otras construcciones como bar.foo && bar.foo.baz se usan incorrectamente con más frecuencia. Pero eso es según el equipo de TS, no yo. 🤷‍♂️

Enlace del patio de recreo al código

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda