web-dev-qa-db-fra.com

utiliser un objet dans l'énumération TypeScript

J'ai une énumération:

 export enum PizzaSize {
          SMALL =  0,
          MEDIUM = 1,
          LARGE = 2

    }

Mais ici, je voudrais utiliser une paire de valeurs: par exemple SMALL je voudrais dire qu'il a 2 valeurs (0, 100). Comment puis-je faire celui-ci?

Je m'efforce d'utiliser

export enum PizzaSize {
          SMALL =  {key:key, value: value},
         ...

    }

Mais TypeScript n'accepte pas celui-ci.

30
Vahe Akhsakhalyan

Mise à jour: trouvez réponse de @ Javarome ci-dessous, ce qui est plus élégant. Je suggère d'utiliser son chemin.

Si vous devez utiliser Type, essayez d'ajouter du code. utilisation: 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};
    }
}
14
Joe Tse

TypeScript prend en charge les énumérations numériques ou basées sur des chaînes uniquement, vous devez donc émuler les énumérations d'objets avec une classe (ce qui vous permettra de l'utiliser comme type dans une déclaration de fonction):

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;
  }
}

vous pouvez ensuite utiliser les instances prédéfinies pour accéder à leur value:

const mediumVal = PizzaSize.MEDIUM.value;

ou tout autre type de propriété/propriété que vous souhaitez définir dans un PizzaSize.

et grâce à la surcharge de toString(), vous pourrez également imprimer implicitement le nom/la clé enum depuis l'objet:

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

Essayez d'utiliser:

const pizzaSize = {
    small: { key: 0, value: 25 },
    medium: { key: 1, value: 35 },
    large: { key: 2, value: 50 }
}
6
Jarek

Depuis TypeScript 3.4 , vous pouvez utiliser une combinaison de keyof typeof et const assertions pour créer des objets qui peuvent avoir le même type de sécurité que les énumérations, et qui contiennent toujours des valeurs complexes.

En créant un type avec le même nom que le const, vous pouvez avoir les mêmes contrôles d'exhaustivité que les énumérations normales.

La seule verrue est que vous avez besoin d'une clé dans l'objet complexe (j'utilise value ici) pour contenir le nom du membre enum (si quelqu'un peut trouver une fonction d'aide qui peut construire ces objets dans un manière sûre, j'adorerais le voir! Je n'ai pas pu en faire fonctionner un).

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'
    }
}

Dans d'autres fichiers, cela peut être utilisé simplement, il suffit d'importer PizzaSize.

import { PizzaSize } from './pizza'

console.log(PizzaSize.small.key)

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

Notez également que même les objets qui sont généralement mutables ne peuvent pas être mutés avec le as const syntaxe.

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

// this won't compile!! Yay!!
Thing.ONE.one.splice(1, 0, 0)
3
blaineh