paint-brush
El uso de tipos en línea y desestructurados puede dañar su base de código de TypeScriptpor@baransu
1,271 lecturas
1,271 lecturas

El uso de tipos en línea y desestructurados puede dañar su base de código de TypeScript

por Tomasz Cichociński4m2022/10/10
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

El uso de tipos en línea y desestructurados hace que su TypeScript sea menos legible. Quiero mostrarle cómo el uso de la desestructuración lo hace menos legible en TypeScript. Desalienta la creación de funciones auxiliares más pequeñas y la dependencia de la composición para desarrollar la lógica de la función principal. No existe un lugar natural para escribir comentarios de documentación cuando todos los tipos están repletos de desestructuración en la definición de la función. Es solo mucho espacio de código y requiere mucho espacio de líneas de código. Además, se centra en los detalles de implementación además de los detalles de implementación.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - El uso de tipos en línea y desestructurados puede dañar su base de código de TypeScript
Tomasz Cichociński HackerNoon profile picture
0-item


Recientemente vi un tweet de Jamie Kyle sobre el uso de desestructuración, parámetros predeterminados y tipos en línea:


Ese tweet y algunos componentes de React que vi recientemente en mi trabajo diario me inspiraron a escribir esta publicación de blog. ¡Quiero mostrarle cómo el uso de tipos en línea y de desestructuración puede hacer que su TypeScript sea menos legible!


¿Cómo se ve la definición de la función TypeScript?

En JavaScript y TypeScript, puede definir una función utilizando la palabra clave de function o la función lambda/flecha. Ambas formas son válidas pero tienen sus diferencias. Echemos un vistazo a la función simple sendMessage . La lógica de implementación no es relevante para nosotros.


 // sendMessage function written using `function` keyword function sendMessage(message: string) { // function logic } // same sendMessage written as arrow function const sendMessage = (message: string) => { // function logic };


Cuando la definición de la función es bastante simple, la función acepta algunos parámetros de un tipo diferente. Si son primitivas como cadenas o números, todo es legible.


Supongamos que desea pasar información adicional junto con el contenido de su mensaje a la función sendMessage .


 function sendMessage(message: { content: string; senderId: string; replyTo?: string; }) { // you can assess content using `message.content` here }


Como puede ver, TypeScript le permite escribir una definición de tipo en línea para el objeto de message que desea pasar sin especificar el tipo usando la palabra clave type o interface .


Agreguemos Destructuring. Cuando pasa un objeto de message grande a su función, TypeScript permite dividir los argumentos pasados para reducir el código repetitivo de repetir la variable del message muchas veces.


 function sendMessage({ content, senderId, replyTo, }: { content: string; senderId: string; replyTo?: string; }) { // you have access to `content` directly }


¿Por qué creo que es una mala idea y cómo puedes mejorarla?

Puede parecer una buena idea, después de todo, no es necesario que escribas el message tantas veces, ¿verdad? Resulta que no es tan bueno. Hablemos de 5 razones por las que creo que es un antipatrón.


1. No está seguro de dónde provienen sus datos

Cuando está leyendo el cuerpo de la función, ve senderId , tiene que verificar dos veces para asegurarse de dónde proviene esa función. ¿Se pasa como argumento o se calcula en algún lugar de la función?


2. Es difícil escribir documentación

No existe un lugar natural para escribir comentarios de documentación cuando todos los tipos están repletos de desestructuración en la definición de la función. Puede escribir comentarios entre cada campo de tipo, pero eso hace que toda la definición de la función sea aún más larga. Lo está disuadiendo activamente de escribir un resumen rápido de los datos que está pasando.


3. Es difícil transmitir esos datos

Cuando sus datos se desestructuran, debe estructurarlos nuevamente en un nuevo objeto si desea pasarlos. Esto desalienta la creación de funciones auxiliares más pequeñas y la dependencia de la composición para desarrollar la lógica de la función principal.


4. No puede reutilizar tipos de argumentos fuera de esta función

Si necesita reutilizar los argumentos de su función en funciones auxiliares al componer la lógica de su función principal, debe escribir el mismo conjunto de tipos repetidamente. Esto hace que sea más fácil no escribir tipos en absoluto.


5. Solo ocupa mucho espacio

Seamos sinceros. Son solo muchas líneas de código que ocupan mucho espacio en la pantalla. Y además, se enfoca en los detalles de implementación: el tipo interno de los argumentos que está pasando a una función, que la mayoría de las veces no es relevante cuando está mirando esa función.


Solo crea un tipo para ello.

Extraer el tipo y colocarlo justo encima de la función lo hace mucho más legible. Hay un lugar para comentarios de documentación, puede reutilizar ese tipo en alguna otra función auxiliar y cambiar la definición de tipo en un lugar si es necesario.


 /** * Message to send using XYZ API */ export type MessageToSend = { /** * Markdown string of the user's message */ content: string; /** * Id of the sender user */ senderId: string; /** * Other message ID if this is a reply */ replyTo?: string; }; function sendMessage(message: MessageToSend) { // function logic } function getUserIdsToNotify(message: MessaageToSend) { // function logic }


Recursos

Encuentre una lista de recursos que utilicé al investigar esta publicación de blog: