En esta página:
El mundo de JavaScript fue replanteado con la llegada de TypeScript, si has usado herramientas como Node JS, React JS, Angular, Vue JS, Deno, etc. te debas haber topado con estructuras TypeScript. Fuera del nivel de experiencia que tengas, los errores en la programación se puede presentar en cualquier momento y en TypeScript no es la excepción, en este Post te compartiré algunos errores que debes evitar para que tu proyecto funcione sin problemas.
Partes
- Parte 1
- Parte 2 (Final)
Antes de continuar con este Post, te invito a leer los siguientes artículos:
- Que es TypeScript y otros Detalles
- Como usar Path Aliases (Alias de Ruta) con TypeScript en Node JS 13.7
- Diferencia entre Interface y Type en TypeScript
- Union Type y Literal Type en TypeScript
- Creando nuestra primera aplicación “Hola Mundo” con TypeScript 3.9
- Como utilizar TypeScript en Node JS – Parte 1
- Puedes leer más en la categoría TypeScript.
Asimismo te invito a escuchar el Podcast: “Como Hacer De La Programación Un Estilo De Vida”:
Spotify: | Sound Cloud: | Apple Podcasts |
Bien ahora continuemos con el Post: 10 Errores que Debes Evitar en TypeScript – Parte 1.
Para conocer mejor los errores que no debes cometer en TypeScript, colocaré el nombre, una descripción y si es posible un código de ejemplo.
Iterar Innecesariamente las Propiedades del Objeto
Esto se refiere a otra forma en que los tipos any se introducen en el código, nos suele gustar iterar sobre las propiedades del objeto por ejemplo:
1 2 3 4 5 6 7 8 9 10 11 |
interface Postre { nombre: string; precio: number; stock: number; } const postre = { nombre: 'Gelatina de Fresa', precio: 2.50, stock: 48 }; for (const key in postre) { const value = postre[key] // Esto se convierte en un 'any' implícito } |
¿ Que es lo que pasa en el código anterior ? Si hiciéramos algo así const nombre = postre[‘nombre’], la variable tendría un tipo number correcto. Pero si intentamos hacer lo mismo en un bucle, sucederá algo diferente. No estamos haciendo una referencia al valor de la propiedad mediante un ‘nombre’ literal estrecho que el verificador de tipos sabe que es una propiedad existente del tipo Postre, sino utilizando un tipo string más general. Podríamos solucionarlo haciendo uso de la afirmación de tipo const value = postre[key as keyof Postre], pero se sabe que esto no es ideal.
Parece ser un comportamiento extraño, pero TypeScript está haciendo lo correcto, todos los object en TypeScript pueden tener propiedades desconocidas adicionales que pueden contener valores de cualquier tipo. Cuando usamos el método entries(), es decir Object.entries, obtenemos lo mismo: claves string y valores any. Esto quiere decir que iterar sobre las claves de los objetos debería ser una herramienta que no utilizamos en exceso.
Si sabemos que estamos trabajando con datos verdaderamente dinámicos, podemos hacer uso de una index signature y si necesitamos una estructura de datos que modele una colección key/value, tenemos el objeto Map() de ES6 para eso.
Usar el Tipo de Función
A veces es tentador, sobre todo cuando estamos trabajando con código que trata con devoluciones de llamada de varias formas, diferentes listas de parámetros, etc. Por ejemplo:
1 2 3 4 5 |
const aceptarCallback = (callback: Function) => { callback(); }; |
El código anterior nos brinda una forma de manejar todos los escenarios con un tipo al que podemos llamar con cualquier cosa que queramos. Esta es una forma engañosa de hacer las cosas. Podemos llamar a un valor de tipo Function pero trataremos con una llamada de función sin tipo, porque el tipo de retorno siempre será any.
Si tienes la necesidad de utilizar este tipo de solución, talvez sea una señal de que debes reestructurar tu código para poder proporcionar un tipo de información más fuerte.
Usar Aserciones de Tipo en Lugar de Declaraciones de Tipo
Existe una gran diferente entre const postre: Postre = { nombre: ‘Gelatina de Fresa’ } y const postre = { nombre: ‘Gelatina de Fresa’ } as Postre. Esto parece ser algo poco importante para un Desarrollador con experiencia en TypeScript, pero si vemos el segundo ejemplo, este es usado con bastante frecuencia.
Básicamente, en el primer ejemplo le estamos diciendo a TypeScript que verifique si nuestra variable cumple con el tipo especificado y en el segundo ejemplo le decimos al verificador de tipos que sabemos mejor y puede omitir la verificación. Entonces es similar a any y de alguna manera nos ofrece una trampilla de escape del sistema de tipos.
Sin embargo, en un poco menos peligroso porque obtendremos un error si intentamos afirmar algo irrazonable, es decir la escritura undefined as string arrojará un error:
1 2 3 4 5 |
Conversion of type 'undefined' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. |
Lo peor que podemos hacer en este escenario es usar la sugerencia de la segunda parte de este mensaje de error e ir con someValue as unknown as someType lo que silenciará el verificador de tipos.
Agregar Tipos que se Pueden Inferir
Algunos Desarrolladores pueden pensar que este punto se trata sobre problemas con el estilo del código en lugar de errores reales. Personalmente, la línea entre esas 2 áreas suele ser bastante borrosa y la cantidad de errores que pueden evitarse siguiendo una buena guía de estilo a veces puede ser más impresionante que evitando religiosamente las afirmaciones de tipo.
Este punto esta estrictamente relacionado con la legibilidad del código. En el mundo de TypeScript podemos tener tipos implícitos y explícitos:
1 2 3 4 |
const a: number = 4; const b = 4; |
La regla general debería ser: evite siempre agregar tipos donde puedan inferirse. Las anotaciones de tipo redundante agregan más ruido y desordenan tu código y lo hace innecesariamente detallado y más fácil de leer, asimismo hace que la refactorización sea más dolorosa.
No Especificar Tipos de Retorno de Función
Esta es otra excepción a nuestra regla. Deberíamos agregar un tipo de retorno cuando estemos definiendo una función. Siempre necesitamos definir tipos para parámetros de función. Si no lo hacemos, estaremos tratando con un dato any, pero no estamos obligados a definir un tipo de retorno y TypeScript es bastante bueno para inferirlo, por ejemplo:
1 2 3 4 5 |
const compararLongitud = (a: string, b: string) => { return a.length > b.length; }; |
El código anterior muestra muy bien que obtendremos un boolean (booleano). Sin embargo, agregar una anotación de tipo aquí puede ser beneficioso si estamos tratando con una función más compleja, podremos simplemente echarle un vistazo y tener una idea bastante clara de lo que hace sin sumergirnos en su interior.
Además cuando escribimos una función, obtenemos una retroalimentación temprana del compilador que nos permite saber si estamos devolviendo lo que pensamos que es.
Bueno hasta aquí llegamos con esta Parte 1 en donde hemos mencionado 5 errores de 10, que debes evitar cometer en TypeScript.
Ten Paciencia, lo que quiero es que conozcas bien sobre estos errores que debes evitar en TypeScript y no llenarte el capitulo de mucho contenido porque te puedes marear y no tendrás un óptimo aprendizaje.
Nota (s)
- En la siguiente parte y última, mencionaré los 5 últimos errores que debes evitar cometer en TypeScript
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.