El conocimiento es el nuevo dinero.
Aprender es la nueva manera en la que inviertes
Acceso Cursos

Enums de TypeScript VS Union Types

Por qué los Enums de TypeScript son terribles pero los Union Types son geniales

· 6 min de lectura
Enums de TypeScript VS Union Types

Una inmersión profunda en las trampas de los Enums de TypeScript y el poder de los Union Types, o por qué refactorizo todos mis Enums a Union Types.

TypeScript Enums vs. Union Types


Como desarrolladores, estamos constantemente buscando formas de mejorar nuestras bases de código y crear software más fácil de mantener, flexible y robusto. Una de las mejores formas de conseguirlo es aprovechando los puntos fuertes de los diferentes paradigmas de programación y características del lenguaje. En este artículo, exploraremos por qué los Enums de TypeScript son una opción subóptima para muchos casos de uso y cómo los Union Types pueden ofrecer una alternativa superior.

Los múltiples problemas con los Enums de TypeScript


Enums, abreviatura de enumeraciones, es un concepto tomado de lenguajes como C# y Java. Permiten a los desarrolladores definir un conjunto de constantes con nombre que representan un tipo específico. A primera vista, los Enums en TypeScript parecen una gran manera de mejorar la seguridad de tipos y la legibilidad del código. Sin embargo, vienen con una serie de inconvenientes que pueden superar sus beneficios en ciertos escenarios.

Tiempo de ejecución y sobrecarga de compilación


Uno de los principales problemas de los Enums es que añaden sobrecarga de tiempo de ejecución y compilación a tu código base. Los Enums de TypeScript se compilan en objetos JavaScript con claves tanto para los nombres como para los valores de los miembros del Enum. Esto resulta en archivos de salida más grandes y consumo de memoria adicional, lo que puede ser particularmente problemático en aplicaciones de rendimiento crítico.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

// Compiled JavaScript
"use strict";
var Direction;
(function (Direction) {
  Direction[(Direction["Up"] = 0)] = "Up";
  Direction[(Direction["Down"] = 1)] = "Down";
  Direction[(Direction["Left"] = 2)] = "Left";
  Direction[(Direction["Right"] = 3)] = "Right";
})(Direction || (Direction = {}));

Flexibilidad limitada


Los Enums también son bastante rígidos, proporcionando una flexibilidad limitada cuando se trata de modificar o ampliar sus valores. Por ejemplo, si quisiera añadir un nuevo miembro a un Enum, tendría que actualizar cada lugar de su código base que utilice ese Enum, lo que puede llevar mucho tiempo y dar lugar a errores.

Desafíos de la refactorización


La refactorización de Enums puede suponer un reto, especialmente cuando se trata de cambiar el nombre de los miembros. Dado que los Enums se compilan en objetos JavaScript con claves tanto para los nombres como para los valores de los miembros Enum, cambiar el nombre de un miembro Enum puede romper el código de forma inesperada, ya que también cambia el valor correspondiente. Esto puede dar lugar a errores sutiles difíciles de detectar.

Adoptar los tipos Union en lugar de los Enums de TypeScript


A diferencia de los Enums, los Union Types son una alternativa más flexible, ligera y fácil de mantener para representar un conjunto fijo de valores. Ofrecen varias ventajas sobre los Enums, que discutiremos a continuación.

Recuerda que si quieres aprender TypeScript te dejo mi curso

Simplicidad y rendimiento


Los Tipos Unión son más sencillos que los Enums, ya que no requieren ningún tiempo de ejecución o compilación adicional. En lugar de crear un objeto separado, los Tipos Unión definen un nuevo tipo que es la unión de un conjunto de tipos literales. Esto los hace más eficientes en términos de uso de memoria y tamaño de archivo.

type Direction = "Up" | "Down" | "Left" | "Right";

Mayor flexibilidad y extensibilidad


Los tipos Union son también más flexibles y extensibles que los Enums. Añadir o eliminar miembros de un Union Type es tan sencillo como actualizar la definición del tipo, sin necesidad de modificar otras partes de su código base. Además, los tipos Unión pueden combinarse utilizando intersecciones y otras operaciones de tipo, lo que permite una mayor composibilidad y reutilización.

type DiagonalDirection = "UpLeft" | "UpRight" | "DownLeft" | "DownRight";
type AllDirections = Direction | DiagonalDirection;

Refactorización más sencilla


La refactorización de los tipos de unión es más sencilla que la de los Enums. Dado que los tipos de unión no generan objetos JavaScript independientes con claves para los nombres y los valores, cambiar el nombre de un miembro de un tipo de unión no afecta al comportamiento del código en tiempo de ejecución. Esto facilita la refactorización del código sin introducir errores sutiles.

Comparación de IntelliSense para Enums vs. Tipos Unión


Visual Studio Code (VS Code) es un popular editor de código que ofrece potentes funciones IntelliSense, que pueden mejorar la experiencia de desarrollo cuando se trabaja con TypeScript.

Tanto los Enums como los Union Types se benefician de un excelente soporte IntelliSense en VS Code, con algunas diferencias en cómo se presenta la información.

IntelliSense para Enums


En primer lugar, exploremos el soporte de IntelliSense para Enums en VS Code, que es bueno pero no excelente.

Cuando se utilizan Enums, el IntelliSense de VS Code proporciona autocompletado tanto para el tipo Enum como para sus miembros. Esto puede ayudar a acelerar el proceso de desarrollo reduciendo la probabilidad de errores tipográficos y de otro tipo.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

function move(direction: Direction) {
  // ...
}

// Autocomplete suggests Enum members when calling the move function
move(Direction.Up);

Además, al pasar el ratón por encima de un miembro de Enum se mostrará el valor asociado a ese miembro, lo que ofrece más información sobre su código.

IntelliSense para tipos de unión


El soporte de IntelliSense de VS Code para los tipos de unión es incluso mejor que para los Enums, al menos si prefiere trabajar con cadenas como Up

Cuando se utilizan tipos de unión, VS Code proporciona autocompletado para los miembros del tipo, lo que facilita la escritura de código que utilice el conjunto de valores definido.

type Direction = "Up" | "Down" | "Left" | "Right";

function move(direction: Direction) {
  // ...
}

// Autocomplete suggests Union Type members when calling the move function
move("Up");

Además, al pasar el ratón por encima de un miembro de un tipo de unión se mostrará la información del tipo, lo que puede ayudarle a comprender la estructura de su código y los valores válidos para un tipo determinado.

Comparación de IntelliSense para Enums vs. Tipos de Unión


Tanto los Enums como los Union Types tienen un excelente soporte en el IntelliSense de VS Code, proporcionando autocompletado e información de tipo cuando es necesario. Sin embargo, hay algunas diferencias sutiles en la forma en que se presenta esta información:

Valores de Miembro

Al pasar el puntero del ratón sobre un miembro Enum, VS Code muestra el valor asociado al miembro (por ejemplo, Direction.Up = 0).

Por el contrario, al pasar el puntero del ratón sobre un miembro de tipo Unión se muestra la información del tipo (por ejemplo, Dirección = "Arriba" | "Abajo" | "Izquierda" | "Derecha").


Composición de tipos

Los tipos de unión ofrecen una mayor flexibilidad en términos de composición de tipos y pueden combinarse fácilmente utilizando intersecciones y otras operaciones de tipos.

El soporte de IntelliSense para tipos de unión complejos puede proporcionar información valiosa sobre la estructura y los valores válidos de estos tipos, facilitando el trabajo con ellos.


Personalmente, encuentro mucho más fácil trabajar con Tipos Unión que con Enums cuando se trata de Intellisense. Normalmente me preocupan preguntas como:

  • "¿Qué valor se está utilizando aquí?"
  • "¿Qué valores son válidos aquí?
  • "¿Por qué no puedo simplemente pasar una cadena a este enum?".

A la hora de elegir entre Enums y Union Types, tenga en cuenta las ventajas y desventajas comentadas anteriormente en este artículo, como la capacidad de mantenimiento, la flexibilidad y el rendimiento, pero también considere qué experiencia de IntelliSense prefiere. Para mí, este es el factor decisivo a favor de los tipos de unión.

Migración de Enums a Union Types


Si estás convencido de que los Union Types se adaptan mejor a tu caso de uso, puede que te preguntes cómo migrar tu código de Enums a Union Types. Aquí tienes una guía paso a paso para ayudarte en el proceso:

Identificar los Enums a reemplazar


Antes de realizar cualquier cambio, identifique los Enums en su código base que le gustaría reemplazar con Union Types. Céntrese en los Enums que le están causando más problemas en términos de mantenimiento, flexibilidad o rendimiento.

Crear el Tipo Unión


Defina un nuevo Tipo Unión que represente el mismo conjunto de valores que el Enum. Utilice literales de cadena para definir los miembros del Tipo Unión.

// Replace this Enum:
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

// With this Union Type:
type Direction = "Up" | "Down" | "Left" | "Right";

Actualiza las anotaciones de tipo


Reemplace todas las anotaciones de tipo en su código que hagan referencia al Enum con el nuevo Tipo Unión.

// Before
function move(direction: Direction) {
  // ...
}

// After
function move(direction: Direction) {
  // ...
}

Reemplazar referencias a miembros de Enum


Actualiza todas las referencias a los miembros de Enum con sus correspondientes literales de cadena.

// Before
move(Direction.Up);

// After
move("Up");

Eliminar el Enum


Una vez actualizadas todas las referencias al Enum, puede eliminarlo de su código y empezar a disfrutar de sus nuevos Union Types.

Siguiendo estos pasos, puedes migrar gradualmente tu código de Enums a Union Types, cosechando los beneficios de una mejor mantenibilidad, flexibilidad y rendimiento junto con mejores sugerencias de IntelliSense.

Conclusión

Los Enums son demasiado Java para mi gusto
Mientras que los Enums pueden ser una característica útil en ciertos escenarios, vienen con desventajas significativas que pueden obstaculizar el desarrollo y mantenimiento de su base de código TypeScript.

Los tipos Union ofrecen una alternativa más flexible, ligera y fácil de mantener para representar conjuntos fijos de valores, sin la sobrecarga y rigidez de los Enums.

Comprendiendo las ventajas y desventajas y aprovechando los puntos fuertes de los tipos Union, puedes crear aplicaciones TypeScript más robustas y eficientes.

¡Feliz codigo! ☕

Fuente

Plataforma de cursos gratis sobre programación