{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/enums.html","result":{"data":{"allSitePage":{"nodes":[{"path":"/dev-404-page/"},{"path":"/docs/handbook/advanced-types.html"},{"path":"/docs/handbook/basic-types.html"},{"path":"/docs/handbook/classes.html"},{"path":"/docs/handbook/compiler-options-in-msbuild.html"},{"path":"/docs/handbook/compiler-options.html"},{"path":"/docs/handbook/configuring-watch.html"},{"path":"/docs/handbook/declaration-merging.html"},{"path":"/docs/handbook/decorators.html"},{"path":"/docs/handbook/enums.html"},{"path":"/docs/handbook/functions.html"},{"path":"/docs/handbook/generics.html"},{"path":"/docs/handbook/integrating-with-build-tools.html"},{"path":"/docs/handbook/interfaces.html"},{"path":"/docs/handbook/iterators-and-generators.html"},{"path":"/docs/handbook/jsdoc-supported-types.html"},{"path":"/docs/handbook/jsx.html"},{"path":"/docs/handbook/literal-types.html"},{"path":"/docs/handbook/mixins.html"},{"path":"/docs/handbook/module-resolution.html"},{"path":"/docs/handbook/modules.html"},{"path":"/docs/handbook/namespaces-and-modules.html"},{"path":"/docs/handbook/namespaces.html"},{"path":"/docs/handbook/nightly-builds.html"},{"path":"/docs/handbook/project-references.html"},{"path":"/docs/handbook/symbols.html"},{"path":"/docs/handbook/"},{"path":"/docs/handbook/triple-slash-directives.html"},{"path":"/docs/handbook/type-checking-javascript-files.html"},{"path":"/docs/handbook/type-compatibility.html"},{"path":"/docs/handbook/type-inference.html"},{"path":"/docs/handbook/unions-and-intersections.html"},{"path":"/docs/handbook/utility-types.html"},{"path":"/docs/handbook/variable-declarations.html"},{"path":"/docs/handbook/writing-declaration-files.html"},{"path":"/docs/handbook/declaration-files/by-example.html"},{"path":"/docs/handbook/declaration-files/consumption.html"},{"path":"/docs/handbook/declaration-files/deep-dive.html"},{"path":"/docs/handbook/declaration-files/do-s-and-don-ts.html"},{"path":"/docs/handbook/declaration-files/introduction.html"},{"path":"/docs/handbook/declaration-files/library-structures.html"},{"path":"/docs/handbook/declaration-files/publishing.html"},{"path":"/docs/handbook/declaration-files/templates.html"},{"path":"/docs/handbook/release-notes/typescript-1-1.html"},{"path":"/docs/handbook/release-notes/typescript-1-3.html"},{"path":"/docs/handbook/release-notes/typescript-1-4.html"},{"path":"/docs/handbook/release-notes/typescript-1-5.html"},{"path":"/docs/handbook/release-notes/typescript-1-6.html"},{"path":"/docs/handbook/release-notes/typescript-1-7.html"},{"path":"/docs/handbook/release-notes/typescript-1-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-0.html"},{"path":"/docs/handbook/release-notes/typescript-2-2.html"},{"path":"/docs/handbook/release-notes/typescript-2-1.html"},{"path":"/docs/handbook/release-notes/typescript-2-3.html"},{"path":"/docs/handbook/release-notes/typescript-2-4.html"},{"path":"/docs/handbook/release-notes/typescript-2-5.html"},{"path":"/docs/handbook/release-notes/typescript-2-6.html"},{"path":"/docs/handbook/release-notes/typescript-2-7.html"},{"path":"/docs/handbook/release-notes/typescript-2-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-9.html"},{"path":"/docs/handbook/release-notes/typescript-3-0.html"},{"path":"/docs/handbook/release-notes/typescript-3-1.html"},{"path":"/docs/handbook/release-notes/typescript-3-2.html"},{"path":"/docs/handbook/release-notes/typescript-3-3.html"},{"path":"/docs/handbook/release-notes/typescript-3-4.html"},{"path":"/docs/handbook/release-notes/typescript-3-5.html"},{"path":"/docs/handbook/release-notes/typescript-3-6.html"},{"path":"/docs/handbook/release-notes/typescript-3-7.html"},{"path":"/docs/handbook/release-notes/typescript-3-8.html"},{"path":"/docs/handbook/asp-net-core.html"},{"path":"/docs/handbook/angular.html"},{"path":"/docs/handbook/dom-manipulation.html"},{"path":"/docs/handbook/gulp.html"},{"path":"/docs/handbook/migrating-from-javascript.html"},{"path":"/docs/handbook/react-&-webpack.html"},{"path":"/docs/handbook/react.html"},{"path":"/docs/handbook/typescript-in-5-minutes-func.html"},{"path":"/docs/handbook/typescript-in-5-minutes.html"},{"path":"/docs/handbook/typescript-in-5-minutes-oop.html"},{"path":"/docs/handbook/typescript-from-scratch.html"},{"path":"/docs/handbook/typescript-tooling-in-5-minutes.html"},{"path":"/docs/handbook/tsconfig-json.html"},{"path":"/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-class-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-function-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-d-ts.html"},{"path":"/docs/handbook/release-notes/overview.html"},{"path":"/tsconfig"},{"path":"/en/tsconfig"},{"path":"/ja/tsconfig"},{"path":"/vo/tsconfig"},{"path":"/play"},{"path":"/en/play"},{"path":"/es/play"},{"path":"/vo/play"},{"path":"/zh/play"},{"path":"/ja/play"},{"path":"/play/3-7/fixits/big-number-literals.ts"},{"path":"/play/3-7/fixits/const-to-let.ts"},{"path":"/play/3-7/fixits/infer-from-usage-changes.ts"},{"path":"/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/play/3-7/syntax-and-messaging/nullish-coalescing.ts"},{"path":"/play/3-7/syntax-and-messaging/optional-chaining.ts"},{"path":"/play/3-7/types-and-code-flow/assertion-functions.ts"},{"path":"/play/3-7/types-and-code-flow/recursive-type-references.ts"},{"path":"/play/3-7/types-and-code-flow/uncalled-function-checks.ts"},{"path":"/play/3-8/breaking-changes/checking-unions-with-index-signatures.ts"},{"path":"/play/3-8/jsdoc-improvements/accessibility-modifiers.js"},{"path":"/play/3-8/syntax-and-messaging/export-modules-from.ts"},{"path":"/play/3-8/syntax-and-messaging/private-class-fields.ts"},{"path":"/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/play/javascript/external-apis/typescript-with-node.js"},{"path":"/play/javascript/external-apis/typescript-with-web.js"},{"path":"/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/play/javascript/helping-with-javascript/errors.ts"},{"path":"/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/play/javascript/javascript-essentials/functions.ts"},{"path":"/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/play/javascript/modern-javascript/async-await.ts"},{"path":"/play/javascript/modern-javascript/immutability.ts"},{"path":"/play/javascript/modern-javascript/import-export.ts"},{"path":"/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/play/javascript/working-with-classes/classes-101.ts"},{"path":"/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/play/javascript/working-with-classes/mixins.ts"},{"path":"/play/javascript/working-with-classes/this.ts"},{"path":"/play/playground/config/javascript-playgrounds.js"},{"path":"/play/playground/config/new-compiler-defaults.ts"},{"path":"/play/playground/language/automatic-type-acquisition.ts"},{"path":"/play/playground/language/fixits.ts"},{"path":"/play/playground/tooling/mobile-support.ts"},{"path":"/play/playground/tooling/sharable-urls.ts"},{"path":"/play/playground/tooling/typescript-versions.ts"},{"path":"/play/typescript/language/soundness.ts"},{"path":"/play/typescript/language/structural-typing.ts"},{"path":"/play/typescript/language/type-guards.ts"},{"path":"/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/play/typescript/language-extensions/enums.ts"},{"path":"/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/play/typescript/meta-types/conditional-types.ts"},{"path":"/play/typescript/meta-types/discriminate-types.ts"},{"path":"/play/typescript/meta-types/indexed-types.ts"},{"path":"/play/typescript/meta-types/mapped-types.ts"},{"path":"/play/typescript/primitives/any.ts"},{"path":"/play/typescript/primitives/literals.ts"},{"path":"/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/play/typescript/primitives/unknown-and-never.ts"},{"path":"/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/play/typescript/type-primitives/nullable-types.ts"},{"path":"/play/typescript/type-primitives/tuples.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-node.js"},{"path":"/es/play/javascript/external-apis/typescript-with-web.js"},{"path":"/es/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/es/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/es/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/es/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/es/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/es/play/typescript/type-primitives/nullable-types.ts"},{"path":"/es/play/typescript/type-primitives/tuples.ts"},{"path":"/ja/play/typescript/language-extensions/enums.ts"},{"path":"/ja/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/ja/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/ja/play/typescript/primitives/any.ts"},{"path":"/ja/play/typescript/primitives/literals.ts"},{"path":"/ja/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/ja/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/vo/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/vo/play/javascript/javascript-essentials/functions.ts"},{"path":"/vo/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/vo/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-node.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-web.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/zh/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/zh/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/zh/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/zh/play/javascript/helping-with-javascript/errors.ts"},{"path":"/zh/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/zh/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/zh/play/javascript/javascript-essentials/functions.ts"},{"path":"/zh/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/zh/play/javascript/modern-javascript/import-export.ts"},{"path":"/zh/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/zh/play/javascript/working-with-classes/classes-101.ts"},{"path":"/zh/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/zh/play/javascript/working-with-classes/mixins.ts"},{"path":"/zh/play/javascript/working-with-classes/this.ts"},{"path":"/zh/play/playground/config/javascript-playgrounds.js"},{"path":"/zh/play/playground/config/new-compiler-defaults.ts"},{"path":"/zh/play/playground/language/automatic-type-acquisition.ts"},{"path":"/zh/play/playground/language/fixits.ts"},{"path":"/zh/play/playground/tooling/mobile-support.ts"},{"path":"/zh/play/playground/tooling/sharable-urls.ts"},{"path":"/zh/play/playground/tooling/typescript-versions.ts"},{"path":"/zh/play/typescript/language/soundness.ts"},{"path":"/zh/play/typescript/language/structural-typing.ts"},{"path":"/zh/play/typescript/language/type-guards.ts"},{"path":"/zh/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/zh/play/typescript/language-extensions/enums.ts"},{"path":"/zh/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/zh/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/zh/play/typescript/meta-types/conditional-types.ts"},{"path":"/zh/play/typescript/meta-types/discriminate-types.ts"},{"path":"/zh/play/typescript/meta-types/indexed-types.ts"},{"path":"/zh/play/typescript/meta-types/mapped-types.ts"},{"path":"/zh/play/typescript/primitives/any.ts"},{"path":"/zh/play/typescript/primitives/literals.ts"},{"path":"/zh/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/zh/play/typescript/primitives/unknown-and-never.ts"},{"path":"/zh/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/zh/play/typescript/type-primitives/nullable-types.ts"},{"path":"/zh/play/typescript/type-primitives/tuples.ts"},{"path":"/zh/play/javascript/modern-javascript/immutability.ts"},{"path":"/zh/play/javascript/modern-javascript/async-await.ts"},{"path":"/zh/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/community"},{"path":"/es/community"},{"path":"/ja/community"},{"path":"/vo/community"},{"path":"/zh/community"},{"path":"/download"},{"path":"/es/download"},{"path":"/ja/download"},{"path":"/vo/download"},{"path":"/zh/download"},{"path":"/empty"},{"path":"/es/empty"},{"path":"/ja/empty"},{"path":"/vo/empty"},{"path":"/zh/empty"},{"path":"/"},{"path":"/es/"},{"path":"/ja/"},{"path":"/vo/"},{"path":"/zh/"},{"path":"/tools"},{"path":"/es/tools"},{"path":"/ja/tools"},{"path":"/vo/tools"},{"path":"/zh/tools"},{"path":"/why-create-typescript"},{"path":"/es/why-create-typescript"},{"path":"/ja/why-create-typescript"},{"path":"/vo/why-create-typescript"},{"path":"/zh/why-create-typescript"},{"path":"/docs/home"},{"path":"/es/docs/home"},{"path":"/ja/docs/home"},{"path":"/vo/docs/home"},{"path":"/zh/docs/home"},{"path":"/dev/playground-plugins/"},{"path":"/dev/sandbox/"},{"path":"/dev/twoslash/"},{"path":"/dev/typescript-vfs/"}]},"markdownRemark":{"id":"c1ef2319-894d-5ddb-aff4-238a7ed657f6","excerpt":"Enums are one of the few features TypeScript has which is not a type-level extension of JavaScript. Enums allow a developer to define a set of named constants…","html":"<p>Enums are one of the few features TypeScript has which is not a type-level extension of JavaScript.</p>\n<p>Enums allow a developer to define a set of named constants.\nUsing enums can make it easier to document intent, or create a set of distinct cases.\nTypeScript provides both numeric and string-based enums.</p>\n<h2 id=\"numeric-enums\" style=\"position:relative;\"><a href=\"#numeric-enums\" aria-label=\"numeric enums permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Numeric enums</h2>\n<p>We’ll first start off with numeric enums, which are probably more familiar if you’re coming from other languages.\nAn enum can be defined using the <code>enum</code> keyword.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Direction {</span>\n<span style=\"color: #000000\">  Up = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Down,</span>\n<span style=\"color: #000000\">  Left,</span>\n<span style=\"color: #000000\">  Right</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Above, we have a numeric enum where <code>Up</code> is initialized with <code>1</code>.\nAll of the following members are auto-incremented from that point on.\nIn other words, <code>Direction.Up</code> has the value <code>1</code>, <code>Down</code> has <code>2</code>, <code>Left</code> has <code>3</code>, and <code>Right</code> has <code>4</code>.</p>\n<p>If we wanted, we could leave off the initializers entirely:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Direction {</span>\n<span style=\"color: #000000\">  Up,</span>\n<span style=\"color: #000000\">  Down,</span>\n<span style=\"color: #000000\">  Left,</span>\n<span style=\"color: #000000\">  Right</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Here, <code>Up</code> would have the value <code>0</code>, <code>Down</code> would have <code>1</code>, etc.\nThis auto-incrementing behavior is useful for cases where we might not care about the member values themselves, but do care that each value is distinct from other values in the same enum.</p>\n<p>Using an enum is simple: just access any member as a property off of the enum itself, and declare types using the name of the enum:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Response {</span>\n<span style=\"color: #000000\">  No = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Yes = </span><span style=\"color: #09835A\">1</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> respond(recipient: string, message: Response): void {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">respond(</span><span style=\"color: #A31515\">\"Princess Caroline\"</span><span style=\"color: #000000\">, Response.Yes);</span></code></div></pre>\n<p>Numeric enums can be mixed in <a href=\"#computed-and-constant-members\">computed and constant members (see below)</a>.\nThe short story is, enums without initializers either need to be first, or have to come after numeric enums initialized with numeric constants or other constant enum members.\nIn other words, the following isn’t allowed:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E {</span>\n<span style=\"color: #000000\">  A = getSomeValue(),</span>\n<span style=\"color: #000000\">  B </span><span style=\"color: #008000\">// Error! Enum member must have initializer.</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h2 id=\"string-enums\" style=\"position:relative;\"><a href=\"#string-enums\" aria-label=\"string enums permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>String enums</h2>\n<p>String enums are a similar concept, but have some subtle <a href=\"#enums-at-runtime\">runtime differences</a> as documented below.\nIn a string enum, each member has to be constant-initialized with a string literal, or with another string enum member.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Direction {</span>\n<span style=\"color: #000000\">  Up = </span><span style=\"color: #A31515\">\"UP\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Down = </span><span style=\"color: #A31515\">\"DOWN\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Left = </span><span style=\"color: #A31515\">\"LEFT\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Right = </span><span style=\"color: #A31515\">\"RIGHT\"</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>While string enums don’t have auto-incrementing behavior, string enums have the benefit that they “serialize” well.\nIn other words, if you were debugging and had to read the runtime value of a numeric enum, the value is often opaque - it doesn’t convey any useful meaning on its own (though <a href=\"#enums-at-runtime\">reverse mapping</a> can often help), string enums allow you to give a meaningful and readable value when your code runs, independent of the name of the enum member itself.</p>\n<h2 id=\"heterogeneous-enums\" style=\"position:relative;\"><a href=\"#heterogeneous-enums\" aria-label=\"heterogeneous enums permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Heterogeneous enums</h2>\n<p>Technically enums can be mixed with string and numeric members, but it’s not clear why you would ever want to do so:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> BooleanLikeHeterogeneousEnum {</span>\n<span style=\"color: #000000\">  No = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Yes = </span><span style=\"color: #A31515\">\"YES\"</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Unless you’re really trying to take advantage of JavaScript’s runtime behavior in a clever way, it’s advised that you don’t do this.</p>\n<h2 id=\"computed-and-constant-members\" style=\"position:relative;\"><a href=\"#computed-and-constant-members\" aria-label=\"computed and constant members permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Computed and constant members</h2>\n<p>Each enum member has a value associated with it which can be either <em>constant</em> or <em>computed</em>.\nAn enum member is considered constant if:</p>\n<ul>\n<li>It is the first member in the enum and it has no initializer, in which case it’s assigned the value <code>0</code>:</li>\n</ul>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// E.X is constant:</span>\n<span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E {</span>\n<span style=\"color: #000000\">  X</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<ul>\n<li>It does not have an initializer and the preceding enum member was a <em>numeric</em> constant.\nIn this case the value of the current enum member will be the value of the preceding enum member plus one.</li>\n</ul>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// All enum members in 'E1' and 'E2' are constant.</span>\n\n<span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E1 {</span>\n<span style=\"color: #000000\">  X,</span>\n<span style=\"color: #000000\">  Y,</span>\n<span style=\"color: #000000\">  Z</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E2 {</span>\n<span style=\"color: #000000\">  A = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  B,</span>\n<span style=\"color: #000000\">  C</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<ul>\n<li>\n<p>The enum member is initialized with a constant enum expression.\nA constant enum expression is a subset of TypeScript expressions that can be fully evaluated at compile time.\nAn expression is a constant enum expression if it is:</p>\n<ol>\n<li>a literal enum expression (basically a string literal or a numeric literal)</li>\n<li>a reference to previously defined constant enum member (which can originate from a different enum)</li>\n<li>a parenthesized constant enum expression</li>\n<li>one of the <code>+</code>, <code>-</code>, <code>~</code> unary operators applied to constant enum expression</li>\n<li><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>%</code>, <code>&#x3C;&#x3C;</code>, <code>>></code>, <code>>>></code>, <code>&#x26;</code>, <code>|</code>, <code>^</code> binary operators with constant enum expressions as operands</li>\n</ol>\n<p>It is a compile time error for constant enum expressions to be evaluated to <code>NaN</code> or <code>Infinity</code>.</p>\n</li>\n</ul>\n<p>In all other cases enum member is considered computed.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> FileAccess {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// constant members</span>\n<span style=\"color: #000000\">  None,</span>\n<span style=\"color: #000000\">  Read = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> &lt;&lt; </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  Write = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> &lt;&lt; </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  ReadWrite = Read | Write,</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// computed member</span>\n<span style=\"color: #000000\">  G = </span><span style=\"color: #A31515\">\"123\"</span><span style=\"color: #000000\">.length</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<h2 id=\"union-enums-and-enum-member-types\" style=\"position:relative;\"><a href=\"#union-enums-and-enum-member-types\" aria-label=\"union enums and enum member types permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Union enums and enum member types</h2>\n<p>There is a special subset of constant enum members that aren’t calculated: literal enum members.\nA literal enum member is a constant enum member with no initialized value, or with values that are initialized to</p>\n<ul>\n<li>any string literal (e.g. <code>\"foo\"</code>, <code>\"bar</code>, <code>\"baz\"</code>)</li>\n<li>any numeric literal (e.g. <code>1</code>, <code>100</code>)</li>\n<li>a unary minus applied to any numeric literal (e.g. <code>-1</code>, <code>-100</code>)</li>\n</ul>\n<p>When all members in an enum have literal enum values, some special semantics come to play.</p>\n<p>The first is that enum members also become types as well!\nFor example, we can say that certain members can <em>only</em> have the value of an enum member:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> ShapeKind {</span>\n<span style=\"color: #000000\">  Circle,</span>\n<span style=\"color: #000000\">  Square</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Circle {</span>\n<span style=\"color: #000000\">  kind: ShapeKind.Circle;</span>\n<span style=\"color: #000000\">  radius: number;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">interface</span><span style=\"color: #000000\"> Square {</span>\n<span style=\"color: #000000\">  kind: ShapeKind.Square;</span>\n<span style=\"color: #000000\">  sideLength: number;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> c: Circle = {</span>\n<span style=\"color: #000000\">  kind: ShapeKind.Square, </span><span style=\"color: #008000\">// Error! Type 'ShapeKind.Square' is not assignable to type 'ShapeKind.Circle'.</span>\n<span style=\"color: #000000\">  radius: </span><span style=\"color: #09835A\">100</span>\n<span style=\"color: #000000\">};</span></code></div></pre>\n<p>The other change is that enum types themselves effectively become a <em>union</em> of each enum member.\nWhile we haven’t discussed <a href=\"./Advanced%20Types.md#union-types\">union types</a> yet, all that you need to know is that with union enums, the type system is able to leverage the fact that it knows the exact set of values that exist in the enum itself.\nBecause of that, TypeScript can catch silly bugs where we might be comparing values incorrectly.\nFor example:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E {</span>\n<span style=\"color: #000000\">  Foo,</span>\n<span style=\"color: #000000\">  Bar</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(x: E) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (x !== E.Foo || x !== E.Bar) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">//             ~~~~~~~~~~~</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// Error! This condition will always return 'true' since the types 'E.Foo' and 'E.Bar' have no overlap.</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>In that example, we first checked whether <code>x</code> was <em>not</em> <code>E.Foo</code>.\nIf that check succeeds, then our <code>||</code> will short-circuit, and the body of the ‘if’ will run.\nHowever, if the check didn’t succeed, then <code>x</code> can <em>only</em> be <code>E.Foo</code>, so it doesn’t make sense to see whether it’s equal to <code>E.Bar</code>.</p>\n<h2 id=\"enums-at-runtime\" style=\"position:relative;\"><a href=\"#enums-at-runtime\" aria-label=\"enums at runtime permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enums at runtime</h2>\n<p>Enums are real objects that exist at runtime.\nFor example, the following enum</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> E {</span>\n<span style=\"color: #000000\">  X,</span>\n<span style=\"color: #000000\">  Y,</span>\n<span style=\"color: #000000\">  Z</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>can actually be passed around to functions</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(obj: { X: number }) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> obj.X;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// Works, since 'E' has a property named 'X' which is a number.</span>\n<span style=\"color: #000000\">f(E);</span></code></div></pre>\n<h2 id=\"enums-at-compile-time\" style=\"position:relative;\"><a href=\"#enums-at-compile-time\" aria-label=\"enums at compile time permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enums at compile time</h2>\n<p>Even though Enums are real objects that exist at runtime, the <code>keyof</code> keyword works differently than you might expect for typical objects. Instead, use <code>keyof typeof</code> to get a Type that represents all Enum keys as strings.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> LogLevel {</span>\n<span style=\"color: #000000\">  ERROR,</span>\n<span style=\"color: #000000\">  WARN,</span>\n<span style=\"color: #000000\">  INFO,</span>\n<span style=\"color: #000000\">  DEBUG</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">/**</span>\n<span style=\"color: #008000\"> * This is equivalent to:</span>\n<span style=\"color: #008000\"> * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';</span>\n<span style=\"color: #008000\"> */</span>\n<span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> LogLevelStrings = </span><span style=\"color: #0000FF\">keyof</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">typeof</span><span style=\"color: #000000\"> LogLevel;</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> printImportant(key: LogLevelStrings, message: string) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> num = LogLevel[key];</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (num &lt;= LogLevel.WARN) {</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">\"Log level key is: \"</span><span style=\"color: #000000\">, key);</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">\"Log level value is: \"</span><span style=\"color: #000000\">, num);</span>\n<span style=\"color: #000000\">    console.log(</span><span style=\"color: #A31515\">\"Log level message is: \"</span><span style=\"color: #000000\">, message);</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #000000\">printImportant(</span><span style=\"color: #A31515\">\"ERROR\"</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"This is a message\"</span><span style=\"color: #000000\">);</span></code></div></pre>\n<h3 id=\"reverse-mappings\" style=\"position:relative;\"><a href=\"#reverse-mappings\" aria-label=\"reverse mappings permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reverse mappings</h3>\n<p>In addition to creating an object with property names for members, numeric enums members also get a <em>reverse mapping</em> from enum values to enum names.\nFor example, in this example:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Enum {</span>\n<span style=\"color: #000000\">  A</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a = Enum.A;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> nameOfA = Enum[a]; </span><span style=\"color: #008000\">// \"A\"</span></code></div></pre>\n<p>TypeScript might compile this down to something like the following JavaScript:</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> Enum;</span>\n<span style=\"color: #000000\">(</span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">(Enum) {</span>\n<span style=\"color: #000000\">  Enum[(Enum[</span><span style=\"color: #A31515\">\"A\"</span><span style=\"color: #000000\">] = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">)] = </span><span style=\"color: #A31515\">\"A\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">})(Enum || (Enum = {}));</span>\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> a = Enum.A;</span>\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> nameOfA = Enum[a]; </span><span style=\"color: #008000\">// \"A\"</span></code></div></pre>\n<p>In this generated code, an enum is compiled into an object that stores both forward (<code>name</code> -> <code>value</code>) and reverse (<code>value</code> -> <code>name</code>) mappings.\nReferences to other enum members are always emitted as property accesses and never inlined.</p>\n<p>Keep in mind that string enum members <em>do not</em> get a reverse mapping generated at all.</p>\n<h3 id=\"const-enums\" style=\"position:relative;\"><a href=\"#const-enums\" aria-label=\"const enums permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>const</code> enums</h3>\n<p>In most cases, enums are a perfectly valid solution.\nHowever sometimes requirements are tighter.\nTo avoid paying the cost of extra generated code and additional indirection when accessing enum values, it’s possible to use <code>const</code> enums.\nConst enums are defined using the <code>const</code> modifier on our enums:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Enum {</span>\n<span style=\"color: #000000\">  A = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  B = A * </span><span style=\"color: #09835A\">2</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Const enums can only use constant enum expressions and unlike regular enums they are completely removed during compilation.\nConst enum members are inlined at use sites.\nThis is possible since const enums cannot have computed members.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Directions {</span>\n<span style=\"color: #000000\">  Up,</span>\n<span style=\"color: #000000\">  Down,</span>\n<span style=\"color: #000000\">  Left,</span>\n<span style=\"color: #000000\">  Right</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> directions = [</span>\n<span style=\"color: #000000\">  Directions.Up,</span>\n<span style=\"color: #000000\">  Directions.Down,</span>\n<span style=\"color: #000000\">  Directions.Left,</span>\n<span style=\"color: #000000\">  Directions.Right</span>\n<span style=\"color: #000000\">];</span></code></div></pre>\n<p>in generated code will become</p>\n<pre class=\"shiki\"><div class=\"language-id\">js</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> directions = [</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\"> </span><span style=\"color: #008000\">/* Up */</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\"> </span><span style=\"color: #008000\">/* Down */</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\"> </span><span style=\"color: #008000\">/* Left */</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\"> </span><span style=\"color: #008000\">/* Right */</span><span style=\"color: #000000\">];</span></code></div></pre>\n<h2 id=\"ambient-enums\" style=\"position:relative;\"><a href=\"#ambient-enums\" aria-label=\"ambient enums permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Ambient enums</h2>\n<p>Ambient enums are used to describe the shape of already existing enum types.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">declare</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">enum</span><span style=\"color: #000000\"> Enum {</span>\n<span style=\"color: #000000\">  A = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  B,</span>\n<span style=\"color: #000000\">  C = </span><span style=\"color: #09835A\">2</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>One important difference between ambient and non-ambient enums is that, in regular enums, members that don’t have an initializer will be considered constant if its preceding enum member is considered constant.\nIn contrast, an ambient (and non-const) enum member that does not have initializer is <em>always</em> considered computed.</p>","headings":[{"value":"Numeric enums","depth":2},{"value":"String enums","depth":2},{"value":"Heterogeneous enums","depth":2},{"value":"Computed and constant members","depth":2},{"value":"Union enums and enum member types","depth":2},{"value":"Enums at runtime","depth":2},{"value":"Enums at compile time","depth":2},{"value":"Reverse mappings","depth":3},{"value":"const enums","depth":3},{"value":"Ambient enums","depth":2}],"frontmatter":{"permalink":"/docs/handbook/enums.html","title":"Enums"}}},"pageContext":{"slug":"/docs/handbook/enums.html","isOldHandbook":true}}}