102 votes

Différence entre les énumérations de chaînes et les types littéraux de chaînes dans TS

En supposant que je veux m'assurer que myKey en { myKey: '' } seulement contient les chaînes de caractères foo, bar, baz, j'ai pu réaliser de deux façons.

   // with a String Literal Type 
   type MyKeyType = 'foo' | 'bar' | 'baz';

    // or with a String Enum   
    enum MyKeyType {
       FOO = 'foo',
       BAR = 'bar',
       BAZ = 'baz'
    }

Je me demande où les avantages et les inconvénients de l'un sur l'autre, comme à la fois regarder la même chose pour moi (sauf de la façon dont je voudrais accéder aux valeurs pour par exemple, une condition à vérifier).

La seule différence que j'ai trouvé dans le TS de la documentation est que les Énumérations sont de véritables objets lors de l'exécution, ce qui pourrait être souhaitable dans certains cas.

55voto

Ryan Cavanaugh Points 17393

L'essentiel à comprendre est que les valeurs des énumérations de chaînes sont opaques .

Le cas d'utilisation prévu pour une énumération de chaîne est que vous ne voulez pas qu'un autre code sache ou se soucie de la chaîne littérale qui soutient MyKeyType.FOO . Cela signifie que vous ne pourrez pas, par exemple, transmettre la chaîne littérale "bar" à une fonction acceptant un MyKeyType - vous devrez écrire MyKeyType.BAR place.

52voto

Daniel R Points 176

Eh bien, il y a une différence entre la chaîne des enums et littérale de types dans le transpiled code.

Comparer le Tapuscrit Code

// with a String Literal Type 
type MyKeyType1 = 'foo' | 'bar' | 'baz';

// or with a String Enum   
enum MyKeyType2 {
   FOO = 'foo',
   BAR = 'bar',
   BAZ = 'baz'
}

Avec le transpiled JavaScript Code

// or with a String Enum   
var MyKeyType2;
(function (MyKeyType2) {
    MyKeyType2["FOO"] = "foo";
    MyKeyType2["BAR"] = "bar";
    MyKeyType2["BAZ"] = "baz";
})(MyKeyType2 || (MyKeyType2 = {}));

Ce que vous pouvez voir, il n'y a pas de code généré pour l'un littéral de chaîne. Parce que les Tapuscrits Transpiler est seulement à l'aide de sécurité de type tout transpiling. Au moment de l'exécution des littéraux de chaîne sont "générés de muets" les chaînes. Pas de références entre la définition de la littéralité et les usages.

Donc, il y a une troisième alternative appelée const enum

Regardez cette

// with a String Literal Type 
type MyKeyType1 = 'foo' | 'bar' | 'baz';

// or with a String Enum   
enum MyKeyType2 {
   FOO = 'foo',
   BAR = 'bar',
   BAZ = 'baz'
}

// or with a Const String Enum   
const enum MyKeyType3 {
   FOO = 'foo',
   BAR = 'bar',
   BAZ = 'baz'
}

var a : MyKeyType1 = "bar" 
var b: MyKeyType2 = MyKeyType2.BAR
var c: MyKeyType3 = MyKeyType3.BAR

sera transpiled à

// or with a String Enum   
var MyKeyType2;
(function (MyKeyType2) {
    MyKeyType2["FOO"] = "foo";
    MyKeyType2["BAR"] = "bar";
    MyKeyType2["BAZ"] = "baz";
})(MyKeyType2 || (MyKeyType2 = {}));
var a = "bar";
var b = MyKeyType2.BAR;
var c = "bar" /* BAR */;

Pour plus de jouer, vous pouvez consulter ce lien

Je préfère la const enum cas, car de la façon la plus pratique de taper Enum.De la valeur. La machine fera le reste pour moi d'obtenir les performances les plus élevées lors de la transpiling.

17voto

Frank Modica Points 6849

Un avantage pour un enum au temps de développement que vous pouvez voir la liste des options facilement via intellisense:

enter image description here

De même, vous pouvez modifier une valeur d'enum facilement à l'aide de refactoring, au lieu de changer une chaîne de partout.

Edit: En VS 2017 et Tapuscrit >=3.2.4, intellisense fonctionne avec un littéral de chaîne types:

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X