Saltar al contenido

Usar literal de objeto como valores de enumeración de TypeScript

Solución:

TypeScript solo admite enumeraciones numéricas o basadas en cadenas, por lo que debe emular enumeraciones de objetos con una clase (lo que le permitirá usarlo como un tipo en una declaración de función):

export class PizzaSize {
  static readonly SMALL  = new PizzaSize('SMALL', 'A small pizza');
  static readonly MEDIUM = new PizzaSize('MEDIUM', 'A medium pizza');
  static readonly LARGE  = new PizzaSize('LARGE', 'A large pizza');

  // private to disallow creating other instances of this type
  private constructor(private readonly key: string, public readonly value: any) {
  }

  toString() {
    return this.key;
  }
}

entonces puede usar las instancias predefinidas para acceder a sus value:

const mediumVal = PizzaSize.MEDIUM.value;

o cualquier otra propiedad / tipo de propiedad que desee definir en un PizzaSize.

y gracias a la toString() anulando, también podrá imprimir el nombre / clave de enumeración implícitamente desde el objeto:

console.log(PizzaSize.MEDIUM);  // prints 'MEDIUM'

Actualización: encuentre la respuesta de @ Javarome a continuación, que es más elegante. Sugiero usar su camino.

Si necesita usar Type, intente agregar algún código. uso: getPizzSizeSpec(PizzaSize.small).value

enum PizzaSize {
    small,
    medium,
    large
}
interface PizzaSizeSpec {
    key: number,
    value: number
}
function getPizzaSizeSpec(pizzaSize: PizzaSize): PizzaSizeSpec {
    switch (pizzaSize) {
        case PizzaSize.small:
            return {key:0, value: 25};
        case PizzaSize.medium:
            return {key:0, value: 35};
        case PizzaSize.large:
            return {key:0, value: 50};
    }
}

A partir de Typecript 3.4, puede utilizar una combinación de keyof typeof y const aserciones para crear objetos que pueden tener el mismo tipo de seguridad que las enumeraciones y aún tener valores complejos.

Creando un type con el mismo nombre que el const, puede tener las mismas comprobaciones de exhaustividad que tienen las enumeraciones normales.

La única verruga es que necesitas alguna clave en el objeto complejo (estoy usando value aquí) para mantener el nombre del miembro enum (si alguien puede encontrar una función auxiliar que pueda construir estos objetos de una manera segura, ¡me encantaría verlo! No pude hacer que uno funcione).

export const PizzaSize = {
    small: { value: 'small', key: 0, size: 25 },
    medium: { value: 'medium', key: 1, size: 35 },
    large: { value: 'large', key: 2, size: 50 },
} as const

export type PizzaSize = keyof typeof PizzaSize

// if you remove any of these cases, the function won't compile
// because it can't guarantee that you've returned a string
export function order(p: PizzaSize): string {
    switch (p) {
        case PizzaSize.small.value: return 'just for show'
        case PizzaSize.medium.value: return 'just for show'
        case PizzaSize.large.value: return 'just for show'
    }
}

// you can also just hardcode the strings,
// they'll be type checked
export function order(p: PizzaSize): string {
    switch (p) {
        case 'small': return 'just for show'
        case 'medium': return 'just for show'
        case 'large': return 'just for show'
    }
}

En otros archivos, esto se puede usar simplemente, solo importe PizzaSize.

import { PizzaSize } from './pizza'

console.log(PizzaSize.small.key)

type Order = { size: PizzaSize, person: string }

También observe cómo incluso los objetos que generalmente son mutables no pueden ser mutados con la as const sintaxis.

const Thing = {
    ONE: { one: [1, 2, 3] }
} as const

// this won't compile!! Yay!!
Thing.ONE.one.splice(1, 0, 0)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *