Uno de los grandes motivos para argumentar el no usar Typescript suele ser que el tamaño del bundle generado es mayor que si el código se escribiese de forma nativa en Javascript. Y no le falta peso a este argumento puesto que de estar hablando acerca de FrontEnd, los tiempos de carga y la experiencia de usuario son un punto de gran peso.
En otros ámbitos como puede ser el BackEnd de una aplicación, este argumento deja de tener relevancia, puesto que los usuarios no se ven afectado por ello, y de forma general, el espacio en disco de un servidor no cobra especial relevancia en los sistemas actuales.
Sin embargo, volviendo al primer caso, hay ciertas decisiones que como desarrolladores podemos tomar a la hora de escribir nuestro código para mejorar el tamaño de nuestros bundles. Una de ellas es tener en cuenta a que se transpila cada elemento que definimos en el código y buscar alternativas para ello.
Un enum
no es más que envolver en un objeto determinadas propiedades como
constantes estáticas con valores específicos del negocio tales como: un conjunto
de tipos, valores numéricos o estados del sistema; que pueden ser reutilizadas
en cualquier parte del código.
Esto sirve especialmente para evitar errores de escritura, eliminar definición de valores por todo nuestro código y por consiguiente facilitar refactors, centralizando los mismos.
Este concepto no es nativo de JavaScript, sino que viene heredado de Java, por lo que cuando usemos este tipo de definiciones tendrán que ser transpilados a nativo de forma similar a como ocurre con las clases y los métodos privados en ES5.
Así pues la apariencia de un enum
en Typescript es la siguiente:
export enum Fruits {
apple = "apple",
orange = "orange",
}
Sin embargo al ser transpilado obtenemos el siguiente resultado:
"use strict";
var Fruits;
(function (Fruits) {
Fruits["orange"] = "orange";
Fruits["apple"] = "apple";
})(Fruits || (Fruits = {}));
Si bien no es que suponga un cambio radical en cuanto al código, si que podemos mejorar la performance usando un concepto más simple y cercano al cómo se haría esto en Javascript.
Para ello no haremos otra cosa que definir una constante, a la cual asignaremos
un objeto con propiedades y forzaremos usando el as
que dicha variable o
propiedad no puede ser mutada:
const Fruits = {
orange: 'orange' as const,
apple: 'apple' as const
}
// or better
const Fruits2 = {
orange: 'orange',
apple: 'apple'
} as const
En Javascript esto se traduciría de la siguiente forma:
"use strict";
const Fruits = {
orange: 'orange',
apple: 'apple'
};
// or better
const Fruits2 = {
orange: 'orange',
apple: 'apple'
};
Como podemos observar, el resultado es el mismo.Recordemos que ciertas
funcionalidades como los types
y las interface
solo existen en el ámbito de
Typescript y no son transpiladas a Javascript.
Ahora bien, ¿qué diferencia existe entre la primera y la segunda definición de
Fruits
mostrada anteriormente? Simplemente el como Typescript interpreta
dicha variable. Veamos el mensaje de error mostrado si intentamos mutar la
constante:
Fruits.apple = 'apple2' //Type '"apple2"' is not assignable to type '"apple"'.(2322)
Fruits2.apple = 'apple2' // Cannot assign to 'apple' because it is a read-only property.(2540)
Siendo más correcta la segunda forma debido al error que muestra en caso que intentemos mutar el objeto.
Es cierto que Typescript es una herramienta muy potente para los desarrolladores y que, salvo contados casos, debemos primar la mantenibilidad frente al rendimiento, sin embargo, cuando tenemos que prestar especial atención al rendimiento, podemos desechar determinadas herramientas del Superset en pos de usarlo tal y como haríamos en Javascript, sin perder legibilidad puesto que son herramientas que ya son nativas en el sistema.
Ulises Santana
Después de leer el artículo me dió por juguetear en un playground con el ejemplo y me he dado cuenta de que la alternativa del enum no vale para todos los casos.
Concretamente en el caso en el que quieres usar ese enum como un tipo para asegurarte que cuando se lo pasas como parámetro a una función sean sólo los valores que esperas. En este caso el objeto plano de JavaScript ya que es un valor, no un tipo.
En conclusión, la alternativa nos sirve a nivel de valor, pero no como tipo y valor que es lo que aporta el enum en TypeScript.
UPDATE: navegando por Stack Overflow he encontrado esta solución: si
fuéramos a usar la opción del objeto en JavaScript, en vez de fruit: Fruits
sería fruit: typeof Fruits2[keyof typeof Fruits2]
. Es más verboso que el enum,
pero igualmente válido.
¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.
Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?
Pero espera 🖐 que tenemos un conflicto interno. A nosotros las newsletter nos parecen 💩👎👹 Por eso hemos creado la LEAN LISTA, la primera lista zen, disfrutona y que suena a rock y reggaeton del sector de la programación. Todos hemos recibido newsletters por encima de nuestras posibilidades 😅 por eso este es el compromiso de la Lean Lista