web-dev-qa-db-fra.com

Comment fusionner deux énumérations dans TypeScript

Supposons que j'ai deux énumérations, comme décrit ci-dessous dans TypeScript, puis comment les fusionner

enum Mammals {
    Humans,
    Bats,
    Dolphins
}

enum Reptiles {
    Snakes,
    Alligators,
    Lizards
}

export default Mammals & Reptiles // For Illustration purpose, Consider both the Enums have been merged.

Maintenant, lorsque je import le exported value dans un autre fichier, je devrais pouvoir accéder aux valeurs des deux énumérations. 

import animalTypes from "./animalTypes"

animalTypes.Humans //valid

animalTypes.Snakes // valid

Comment puis-je obtenir une telle fonctionnalité dans Typescript?

6
besrabasant

Je ne vais pas proposer une solution pour fusionner en enums (je ne pouvais pas trouver un moyen approprié de le faire)

Mais si vous voulez quelque chose se comportant comme une énumération de la façon dont vous le consommez, vous pouvez toujours utiliser l'objet fusionné en javascript.

enum Mammals {
    Humans = 'Humans',
    Bats = 'Bats',
    Dolphins = 'Dolphins',
}

enum Reptiles {
  Snakes = 'Snakes',
  Alligators = 'Alligators',
  Lizards = 'Lizards',
}

const Animals = {
   ...Mammals,
   ...Reptiles,
}

Ensuite, vous pouvez utiliser Animals.Snakes ou Animals.Dolphins et les deux doivent être correctement dactylographiés et fonctionner comme un enum

5
Arnaud Bertrand

Une énumération TypeScript contient non seulement les clés que vous définissez, mais également l'inverse numérique, par exemple:

Mammals.Humans === 0 && Mammals[0] === 'Humans'

Maintenant, si vous essayez de les fusionner - par exemple avec Object#assign - vous obtiendrez deux clés ayant la même valeur numérique:

const AnimalTypes = Object.assign({}, Mammals, Reptiles);
console.log(AnimalTypes.Humans === AnimalTypes.Snakes) // true

Et je suppose que ce n'est pas ce que vous voulez.

Une façon d'éviter cela est d'affecter manuellement les valeurs à l'énum et de s'assurer qu'elles sont différentes:

enum Mammals {
    Humans = 0,
    Bats = 1,
    Dolphins = 2
}

enum Reptiles {
    Snakes = 3,
    Alligators = 4,
    Lizards = 5
}

ou moins explicite mais par ailleurs équivalente:

enum Mammals {
    Humans,
    Bats,
    Dolphins
}

enum Reptiles {
    Snakes = 3,
    Alligators,
    Lizards
}

Quoi qu'il en soit, tant que vous vous assurez que les énumérations que vous fusionnez ont des ensembles clé/valeur différents, vous pouvez les fusionner avec Object#assign.

Démo de terrain de jeu

4
Tao

Enums, interfaces et types - une solution de travail pour la fusion d’enums

Ce qui est déroutant ici, ce sont les types et les valeurs.

  • Si vous définissez une valeur (let, const etc.), elle aura une valeur plus du type calculé mais non nommé.
  • Si vous définissez une variable type ou interface, un type nommé sera créé, mais il ne sera en aucune manière exporté ou pris en compte dans le SC final. Cela aide seulement lors de l'écriture de votre application.
  • Si vous créez un enum dans TypeScript, vous créez un nom de type statique que vous pouvez utiliser plus un objet réel fourni à JS que vous pouvez utiliser.

Du manuel TS:

Utiliser une énumération est simple: il suffit d’accéder à un membre en tant que propriété de l’énumération elle-même et de déclarer les types à l’aide du nom de l’énumération.

Donc, si vous Object.assign() deux énumérations, cela créera un nouveau valeur (objet) fusionné, mais pas un nouveau type nommé.

Comme il ne s'agit plus d'une enum, vous perdez l'avantage d'avoir une valeur et un type nommé, mais vous pouvez toujours créer un nom de type séparé en guise d'une solution de contournement.

Heureusement, vous pouvez avoir le même nom pour la valeur et le type, et TS importera les deux si vous les exportez.

// This creates a merged enum, but not a type
const Animals = Object.assign({}, Mammals, Reptiles);

// Workaround: create a named type (typeof Animals won't work here!)
type Animals = Mammals | Reptiles;

Lien de terrain de jeu TS

1
gombosg

Je dirais que la bonne façon de le faire serait de définir un nouveau type:

enum Mammals {
    Humans = 'Humans',
    Bats = 'Bats',
    Dolphins = 'Dolphins',
}

enum Reptiles {
  Snakes = 'Snakes',
  Alligators = 'Alligators',
  Lizards = 'Lizards',
}

type Animals = Mammals | Reptiles;
0
pokrishka