Enums en TypeScript
Tags: enums, typescript, javascript
Published: 2020-04-21 19:16:28

Las enumeraciones son una de las pocas características que tiene TypeScript que no es una extensión de JavaScript de nivel de tipo.

Las enumeraciones permiten a un desarrollador definir un conjunto de constantes con nombre. El uso de enumeraciones puede hacer que sea más fácil documentar la intención o crear un conjunto de casos distintos. TypeScript proporciona enumeraciones numéricas y basadas en cadenas.

## Numeric enums

Primero comenzaremos con enumeraciones numéricas, que probablemente sean más familiares si viene de otros idiomas. Se puede definir una enumeración usando la palabra clave ***enum***.

~~~
enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}
~~~

Arriba, tenemos una enumeración numérica donde Up se inicializa con 1. Todos los siguientes miembros se incrementan automáticamente a partir de ese punto. En otras palabras, Direction.Up tiene el valor 1, Down tiene 2, Left tiene 3 y Right tiene 4.

Si quisiéramos, podríamos dejar los inicializadores por defecto:

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

Aquí, Up tendría el valor 0, Down tendría 1, etc...

Usar una enumeración es simple: simplemente acceda a cualquier miembro como una propiedad fuera de la enumeración misma y declare los tipos utilizando el nombre de la enumeración:
~~~
enum Respuesta {
    No = 0,
    Si = 1
}

function quedate(nombre: string, mensaje: Respuesta): void {
    if (mensaje === 1) {
        console.log(`Hola ${nombre}`);
    } else {
        console.log(`Vete de aqui ${nombre}`);
    }
}

quedate("Pequeña Andreita", Respuesta.Si);
~~~

## String enums

Las enumeraciones de cadena son un concepto similar, pero tienen algunas diferencias sutiles de tiempo de ejecución como se documenta a continuación. En una cadena de enumeración, cada miembro debe inicializarse constantemente con una cadena literal o con otro miembro de cadena de enumeración.

~~~
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT"
}
~~~

Si bien las enumeraciones de cadenas no tienen un comportamiento de incremento automático, las enumeraciones de cadenas tienen el beneficio de que se "serializan" bien. En otras palabras, si estaba depurando y tuvo que leer el valor de tiempo de ejecución de una enumeración numérica, el valor a menudo es opaco: no transmite ningún significado útil por sí solo (aunque la asignación inversa a menudo puede ayudar), las enumeraciones de cadena le permiten para dar un valor significativo y legible cuando se ejecuta su código, independientemente del nombre del miembro ***enum***.


## Heterogeneous enums

Técnicamente, las enumeraciones se pueden mezclar con parametros de cadena y numéricos, pero no está claro por qué querría hacerlo:

~~~
enum BooleanLikeHeterogeneousEnum {
  No = 0,
  Yes = "YES"
}
~~~

## Miembros calculados y constantes

Cada miembro de la enumeración tiene un valor asociado que puede ser constante o calculado . Un miembro de enumeración se considera constante si:

- Es el primer miembro de la enumeración y no tiene inicializador, en cuyo caso se le asigna el valor 0:

~~~
enum E {
  X
}
~~~

- No tiene un inicializador y el miembro de enumeración anterior era una constante numérica . En este caso, el valor del miembro de enumeración actual será el valor del miembro de enumeración anterior más uno.

~~~
enum E1 {
  X,
  Y,
  Z
}

enum E2 {
  A = 1,
  B,
  C
}
~~~

- El miembro enum se inicializa con una expresión enum constante. Una expresión enum constante es un subconjunto de expresiones TypeScript que se pueden evaluar completamente en tiempo de compilación. Una expresión es una expresión de enumeración constante si es:

1. una expresión de enumeración literal (básicamente un literal de cadena o un literal numérico)
2. una referencia al miembro de enumeración constante previamente definido (que puede originarse en una enumeración diferente)
3. una expresión de enumeración constante entre paréntesis
4. uno de los +, -, ~operadores unarios aplica a la expresión enum constante
5. +, -, *, /, %, <<, >>, >>>, &, |, ^Los operadores binarios con expresiones constantes de enumeración como operandos.

En todos los demás casos, el miembro enum se considera calculado.
~~~
enum FileAccess {
  // constant members
  None,
  Read = 1 << 1,
  Write = 1 << 2,
  ReadWrite = Read | Write,
  // computed member
  G = "123".length
}
~~~