Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

264
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda