Comment les différents enum variantes travail à la Machine?
Tapuscrit a un tas de façons différentes de définir un enum:
enum Alpha { X, Y, Z }
const enum Beta { X, Y, Z }
declare enum Gamma { X, Y, Z }
declare const enum Delta { X, Y, Z }
Si j'essaie d'utiliser une valeur de Gamma
au moment de l'exécution, j'obtiens une erreur parce que Gamma
n'est pas défini, mais ce n'est pas le cas pour Delta
ou Alpha
? Ce n' const
ou declare
sur les déclarations ici?
Il y a aussi un preserveConstEnums
compilateur drapeau -- comment cette interagir avec ces?
- je viens d'écrire un article à ce sujet, mais il a plus à voir avec la comparaison const non const enums
Vous devez vous connecter pour publier un commentaire.
Il y a quatre aspects différents de enums en caractères d'imprimerie, vous devez être conscient de. Tout d'abord, quelques définitions:
"objet de recherche"
Si vous écrivez ce enum:
La machine émet l'objet suivant:
Je vais référer à ce que la recherche de l'objet. Son but est double: servir comme une cartographie de chaînes à numéros de, par exemple lors de l'écriture de
Foo.X
ouFoo['X']
, et de servir comme un mappage de numéros de à chaînes. Que la cartographie est utile pour le débogage ou l'enregistrement des fins -- vous aurez souvent la valeur0
ou1
et que vous souhaitez obtenir le correspondant de la chaîne de"X"
ou"Y"
."déclarer" ou "ambiante"
À la Machine, vous pouvez "déclarer" les choses que le compilateur doit connaître, mais en réalité pas émettre de code pour. Ceci est utile lorsque vous avez des bibliothèques comme jQuery qui définissent un objet (par exemple,
$
) que vous souhaitez que les informations de type d', mais n'avez pas besoin de code créé par le compilateur. Les spécifications et autre documentation se réfère à des déclarations de cette façon, comme étant dans une "ambiance" contexte; il est important de noter que toutes les déclarations dans un.d.ts
fichier sont "ambiante" (à exiger explicitementdeclare
modificateur ou implicitement, selon le type de déclaration)."inline"
Pour la performance et le code des raisons de taille, il est souvent préférable d'avoir une référence à un membre enum remplacé par son équivalent numérique, lors de la compilation:
La spec appelle cette substitution, je vais l'appeler inline parce que ça sonne plus frais. Parfois, vous pas voulez enum membres à être incorporé, par exemple parce que la valeur d'énumération pourrait changer dans une prochaine version de l'API.
Enums, comment fonctionnent-ils?
Laisser le décomposer par chaque aspect d'un enum. Malheureusement, chacune de ces quatre sections vont termes de référence de tous les autres, de sorte que vous aurez probablement besoin de lire toute cette affaire plus d'une fois.
calculée vs non-calculé (constante)
Enum membres peuvent être des calculée ou pas. La spécification des appels non-calculée membres constante, mais je vais les appeler non calculée pour éviter la confusion avec const.
Un calculée membre enum est celui dont la valeur n'est pas connue au moment de la compilation. Les références à la membres ne peut pas être incorporé, bien sûr. À l'inverse, un non calculée membre enum est une fois dont la valeur est connu au moment de la compilation. Des références à la non-calculé les membres sont toujours inline.
Qui enum membres sont calculées et qui sont non-est-il calculé? Tout d'abord, tous les membres d'une
const
enum sont constants (c'est à dire non-calculé), comme son nom l'indique. Pour un non-const enum, cela dépend si vous êtes à la recherche à un ambiante (déclarer) enum ou un non-ambient enum.Un membre d'un
declare enum
(c'est à dire ambiante enum) est constante si et seulement si il a un initialiseur. Sinon, il est calculé. Notez que dans undeclare enum
, uniquement numérique initialiseurs sont autorisés. Exemple:Enfin, les membres de la non-déclarer la non-const enums sont toujours considérés comme des être calculée. Cependant, leur initialisation expressions sont réduite à des constantes si elles sont calculables au moment de la compilation. Cela signifie non-const enum membres ne sont jamais inline (ce comportement est modifié en caractères d'imprimerie 1.5, voir "Modifications en caractères d'imprimerie" en bas)
const vs non-const
const
Une déclaration d'enum peut avoir les
const
modificateur. Si un enum estconst
, tous références à ses membres inline.const énumérations ne produisent pas d'une recherche de l'objet lors de la compilation. Pour cette raison, c'est une erreur de référence
Foo
dans le code ci-dessus, sauf dans le cadre d'un membre de référence. Pas deFoo
objet sera présent lors de l'exécution.non-const
Si une déclaration d'enum n'a pas le
const
modificateur, les références à ses membres sont inline seulement si le membre est non calculée. Un non-const, non déclarer enum va produire un objet de recherche.déclarer (ambiante) vs non-déclarer
Une importante préface, c'est que
declare
en caractères d'imprimerie a un sens très précis: Cet objet existe quelque part d'autre. C'est pour décrire existant objets. À l'aide dedeclare
pour définir des objets qui n'existe pas réellement peut avoir de mauvaises conséquences; nous allons les examiner plus tard.déclarer
Un
declare enum
ne seront pas émettre un objet de recherche. Les références de ses membres sont inline si ces membres sont calculées (voir ci-dessus calculées vs non-calculée).Il est important de noter que d'autres formes de référence à un
declare enum
sont permis, par exemple, ce code est pas une erreur de compilation mais sera échec à l'exécution:Cette erreur relève de la catégorie de "Ne mentez pas à le compilateur". Si vous n'avez pas un objet nommé
Foo
au moment de l'exécution, ne pas écrire dedeclare enum Foo
!Un
declare const enum
n'est pas différent d'unconst enum
, sauf dans le cas d' --preserveConstEnums (voir ci-dessous).non-déclarer
Un non-déclarer enum produit une recherche de l'objet si elle n'est pas
const
. Inline est décrit ci-dessus.--preserveConstEnums drapeau
Ce drapeau a exactement un effet: non-déclarer const enums émet un objet de recherche. Inline n'est pas affectée. Ceci est utile pour le débogage.
Erreurs Courantes
L'erreur la plus commune est d'utiliser un
declare enum
quand régulierenum
ouconst enum
serait plus approprié. Une forme courante est: est-ceRappelez-vous la règle d'or: Jamais
declare
des choses qui n'existe pas réellement. Utilisationconst enum
si vous voulez toujours d'inlining ou deenum
si vous voulez la recherche de l'objet.Modifications en caractères d'imprimerie
Entre Tapuscrit 1.4 et 1.5, il y a un changement dans le comportement (voir https://github.com/Microsoft/TypeScript/issues/2183) à tous les membres de la non-déclarer la non-const enums être traités comme calculée, même si elles sont explicitement initialisée avec un littéral. Ce "non le bébé", pour ainsi dire, faire de l'inlining comportement plus prévisible et plus proprement séparant le concept de
const enum
régulier de l'enum
. Avant ce changement, non calculée membres de la non-const énumérations ont été intégrées de façon plus agressive.enum
types, merci!const
déclarée types enum.Il y a quelques choses qui se passent ici. Nous allons y aller au cas par cas.
enum
Tout d'abord, un simple vieux enum. Lorsque compilé en JavaScript, cela va émettre une table de recherche.
La table de recherche ressemble à ceci:
Puis, quand vous avez
Cheese.Brie
en caractères d'imprimerie, il émetCheese.Brie
en JavaScript qui prend la valeur 0.Cheese[0]
émetCheese[0]
et en fait évalue à"Brie"
.const enum
Aucun code n'est réellement émise pour cette! Ses valeurs sont intégrées. Les suivants émettent la valeur 0 lui-même en JavaScript:
const enum
s' inline peut être utile pour des raisons de performances.Mais qu'
Bread[0]
? Cela permettra d'erreur à l'exécution et votre compilateur doit l'attraper. Il n'y a pas de table de recherche et le compilateur n'est pas dans la ligne ici.Noter que dans le cas ci-dessus, le --preserveConstEnums drapeau causera Pain d'émettre une table de recherche. Ses valeurs seront toujours inline bien.
déclarer enum
Comme avec d'autres utilisations de
declare
,declare
émet pas de code et attend de vous que vous avez défini le code ailleurs. Ce n'émet pas de table de recherche:Wine.Red
émetWine.Red
en JavaScript, mais il ne sera pas n'importe quel Vin de table de recherche de référence, donc c'est une erreur, sauf si vous avez défini ailleurs.déclarer const enum
Ce n'émet pas de table de recherche:
Mais il ne inline!
Fruit.Apple
émet de 0. Mais encore une foisFruit[0]
erreur à l'exécution, car il n'est pas incorporé et il n'y a pas de table de recherche.J'ai écrit cela dans cette aire de jeux. Je recommande d'y jouer pour comprendre ce qui Tapuscrit qui émet JavaScript.
Bread[0]
renvoie une erreur de compilateur: “const enum membre ne peut être consulté à l'aide d'une chaîne littérale.”