blog.logrocket.com
Open in
urlscan Pro
2606:4700:10::ac43:2811
Public Scan
URL:
https://blog.logrocket.com/typescript-enums-vs-types/
Submission: On September 29 via api from US — Scanned from DE
Submission: On September 29 via api from US — Scanned from DE
Form analysis
5 forms found in the DOM<form id="commentform" class="comment-form">
<iframe title="Comment Form"
src="https://jetpack.wordpress.com/jetpack-comment/?blogid=217016018&postid=360&comment_registration=0&require_name_email=1&stc_enabled=1&stb_enabled=1&show_avatars=1&avatar_default=mystery&greeting=Leave+a+Reply&jetpack_comments_nonce=d6cd6d7706&greeting_reply=Leave+a+Reply+to+%25s&color_scheme=light&lang=en_US&jetpack_version=12.6.2&show_cookie_consent=10&has_cookie_consent=0&token_key=%3Bnormal%3B&sig=09812ed71b6e4ae0a1111e7147cd526851b0e8c7#parent=https%3A%2F%2Fblog.logrocket.com%2Ftypescript-enums-vs-types%2F"
name="jetpack_remote_comment" style="width: 100%; height: 75px; border: 0px;" class="jetpack_remote_comment" id="jetpack_remote_comment" sandbox="allow-same-origin allow-top-navigation allow-scripts allow-forms allow-popups" scrolling="no">
</iframe>
<!--[if !IE]><!-->
<script>
document.addEventListener('DOMContentLoaded', function() {
var commentForms = document.getElementsByClassName('jetpack_remote_comment');
for (var i = 0; i < commentForms.length; i++) {
commentForms[i].allowTransparency = false;
commentForms[i].scrolling = 'no';
}
});
</script>
<!--<![endif]-->
</form>
GET https://blog.logrocket.com/
<form role="search" method="get" class="search-form" action="https://blog.logrocket.com/">
<input type="hidden" name="post_type" value="post">
<input type="search" class="search-field" placeholder="Search..." value="" name="s" title="Search for:">
<button type="submit" class="search-submit">
<i class="fa fa-search"></i>
</button>
</form>
POST
<form class="auth0-lock-widget" method="post">
<div class="auth0-lock-widget-container">
<div class="auth0-lock-cred-pane auth0-lock-quiet">
<div class="auth0-lock-cred-pane-internal-wrapper">
<div class="auth0-lock-header">
<div class="auth0-lock-header-bg auth0-lock-blur-support">
<div class="auth0-lock-header-bg-blur" style="background-image: url("https://i.imgur.com/b38Ke6P.png");"></div>
<div class="auth0-lock-header-bg-solid" style="background-color: rgb(146, 111, 202);"></div>
</div>
<div class="auth0-lock-header-welcome"><img alt="" class="auth0-lock-header-logo" src="https://i.imgur.com/b38Ke6P.png">
<div class="auth0-lock-name" title="Sign Up">Sign Up</div>
</div>
</div>
<div class="auth0-lock-content-wrapper">
<div>
<div></div>
</div>
<div style="position: relative;"><span>
<div class="">
<div style="visibility: inherit;">
<div class="auth0-lock-view-content">
<div style="position: relative;">
<div class="auth0-lock-body-content">
<div class="auth0-lock-content">
<div class="auth0-lock-form">
<div>
<div>
<div class="auth-lock-social-buttons-pane">
<div class="auth0-lock-social-buttons-container"><button class="auth0-lock-social-button auth0-lock-social-big-button" data-provider="github" type="button">
<div class="auth0-lock-social-button-icon"></div>
<div class="auth0-lock-social-button-text">Sign up with GitHub</div>
</button><button class="auth0-lock-social-button auth0-lock-social-big-button" data-provider="google-oauth2" type="button">
<div class="auth0-lock-social-button-icon"></div>
<div class="auth0-lock-social-button-text">Sign up with Google</div>
</button><button class="auth0-lock-social-button auth0-lock-social-big-button" data-provider="windowslive" type="button">
<div class="auth0-lock-social-button-icon"></div>
<div class="auth0-lock-social-button-text">Sign up with Microsoft Account</div>
</button></div>
</div>
<div class="auth0-lock-pane-separator"></div>
<div>
<p><span>or</span></p>
<div class="auth0-lock-input-block auth0-lock-input-email">
<div class="auth0-lock-input-wrap auth0-lock-input-wrap-with-icon"><span aria-hidden="true"><svg aria-hidden="true" focusable="false" width="14px" height="13px" viewBox="0 0 32 26" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" class="auth0-lock-icon auth0-lock-icon-box">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="32px" sketch:type="MSLayerGroup" transform="translate(-2155.000000, -2317.000000)" fill="#373A39">
<g id="Group-856" transform="translate(1.000000, 1.000000)" sketch:type="MSShapeGroup">
<path id="Fill-419"
d="M2184,2339 C2184,2339.55 2183.55,2340 2183,2340 L2157,2340 C2156.45,2340 2156,2339.55 2156,2339 L2156,2319 C2156,2318.45 2156.45,2318 2157,2318 L2183,2318 C2183.55,2318 2184,2318.45 2184,2319 L2184,2339 L2184,2339 Z M2184,2316 L2156,2316 C2154.89,2316 2154,2316.89 2154,2318 L2154,2340 C2154,2341.1 2154.89,2342 2156,2342 L2184,2342 C2185.1,2342 2186,2341.1 2186,2340 L2186,2318 C2186,2316.89 2185.1,2316 2184,2316 L2184,2316 Z M2176,2322 L2180,2322 L2180,2326 L2176,2326 L2176,2322 Z M2174,2328 L2182,2328 L2182,2320 L2174,2320 L2174,2328 Z M2158,2332 L2172,2332 L2172,2330 L2158,2330 L2158,2332 Z M2158,2336 L2172,2336 L2172,2334 L2158,2334 L2158,2336 Z">
</path>
</g>
</g>
</g>
</svg></span><input type="email" id="2-email" name="email" class="auth0-lock-input" placeholder="yours@example.com" autocomplete="off" autocapitalize="off" aria-label="Email" aria-invalid="false" value="">
</div>
</div>
<div class="auth0-lock-input-block auth0-lock-input-show-password">
<div class="auth0-lock-input-block auth0-lock-input-password">
<div class="auth0-lock-input-wrap auth0-lock-input-wrap-with-icon"><span aria-hidden="true"><svg aria-hidden="true" focusable="false" width="11px" height="14px" viewBox="0 0 13 16" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="auth0-lock-icon auth0-lock-icon-box">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-288.000000, -1508.000000)" fill="#888888">
<path
d="M299,1523.998 L290,1523.998 C288.896,1523.998 288,1523.102 288,1521.999 L288,1515.999 C288,1514.895 288.896,1513.998 290,1513.998 L290,1513.998 L290,1512.499 C290,1510.015 292.015,1507.999 294.5,1507.999 C296.985,1507.999 299,1510.015 299,1512.499 L299,1513.999 C300.104,1513.999 301,1514.895 301,1515.999 L301,1521.999 C301,1523.103 300.104,1523.998 299,1523.998 L299,1523.998 Z M298,1512.499 C298,1510.566 296.433,1508.999 294.5,1508.999 C292.567,1508.999 291,1510.566 291,1512.499 L291,1513.998 L298,1513.998 L298,1512.499 L298,1512.499 Z M300,1515.999 C300,1515.446 299.552,1514.998 299,1514.998 L290,1514.998 C289.447,1514.998 289,1515.446 289,1515.999 L289,1521.999 C289,1522.551 289.447,1522.998 290,1522.998 L299,1522.998 C299.552,1522.998 300,1522.551 300,1521.999 L300,1515.999 L300,1515.999 Z M294.5,1520.998 C294.224,1520.998 294,1520.774 294,1520.498 L294,1517.498 C294,1517.223 294.224,1516.999 294.5,1516.999 C294.776,1516.999 295,1517.223 295,1517.498 L295,1520.498 C295,1520.774 294.776,1520.998 294.5,1520.998 L294.5,1520.998 Z">
</path>
</g>
</g>
</svg></span><input type="password" name="password" class="auth0-lock-input" autocomplete="off" autocapitalize="off" value="" aria-label="Password" aria-invalid="false" placeholder="your password"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div><small class="auth0-lock-terms"><span>By signing up, you agree to our terms of service and privacy policy.</span></small>
</div>
</div>
</div>
</div>
</div>
</span></div>
</div><button class="auth0-lock-submit" name="submit" type="submit" aria-label="Sign Up" style="background-color: rgb(146, 111, 202); display: block;">
<div class="auth0-loading-container">
<div class="auth0-loading"></div>
</div><span class="auth0-label-submit"><!-- react-text: 32 -->Sign Up<!-- /react-text --><span><svg aria-hidden="true" focusable="false" class="icon-text" width="8px" height="12px" viewBox="0 0 8 12" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Web/Submit/Active" transform="translate(-148.000000, -32.000000)" fill="#FFFFFF">
<polygon id="Shape" points="148 33.4 149.4 32 155.4 38 149.4 44 148 42.6 152.6 38"></polygon>
</g>
</g>
</svg></span></span>
</button>
</div>
</div>
</div>
</form>
<form id="mktoForm_1107" style="display: none; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(51, 51, 51); width: 1px;" novalidate="novalidate" class="mktoForm mktoHasWidth mktoLayoutLeft">
<style type="text/css">
.mktoForm .mktoButtonWrap.mktoSimple .mktoButton {
color: #fff;
border: 1px solid #75ae4c;
padding: 0.4em 1em;
font-size: 1em;
background-color: #99c47c;
background-image: -webkit-gradient(linear, left top, left bottom, from(#99c47c), to(#75ae4c));
background-image: -webkit-linear-gradient(top, #99c47c, #75ae4c);
background-image: -moz-linear-gradient(top, #99c47c, #75ae4c);
background-image: linear-gradient(to bottom, #99c47c, #75ae4c);
}
.mktoForm .mktoButtonWrap.mktoSimple .mktoButton:hover {
border: 1px solid #447f19;
}
.mktoForm .mktoButtonWrap.mktoSimple .mktoButton:focus {
outline: none;
border: 1px solid #447f19;
}
.mktoForm .mktoButtonWrap.mktoSimple .mktoButton:active {
background-color: #75ae4c;
background-image: -webkit-gradient(linear, left top, left bottom, from(#75ae4c), to(#99c47c));
background-image: -webkit-linear-gradient(top, #75ae4c, #99c47c);
background-image: -moz-linear-gradient(top, #75ae4c, #99c47c);
background-image: linear-gradient(to bottom, #75ae4c, #99c47c);
}
</style>
<div class="mktoFormRow">
<div class="mktoFieldDescriptor mktoFormCol" style="margin-bottom: 10px;">
<div class="mktoOffset" style="width: 10px;"></div>
<div class="mktoFieldWrap"><label for="FirstName" id="LblFirstName" class="mktoLabel mktoHasWidth" style="width: 100px;">
<div class="mktoAsterix">*</div>First Name:
</label>
<div class="mktoGutter mktoHasWidth" style="width: 10px;"></div><input id="FirstName" name="FirstName" maxlength="255" aria-labelledby="LblFirstName InstructFirstName" type="text" class="mktoField mktoTextField mktoHasWidth"
style="width: 150px;"><span id="InstructFirstName" tabindex="-1" class="mktoInstruction"></span>
<div class="mktoClear"></div>
</div>
<div class="mktoClear"></div>
</div>
<div class="mktoClear"></div>
</div>
<div class="mktoFormRow">
<div class="mktoFieldDescriptor mktoFormCol" style="margin-bottom: 10px;">
<div class="mktoOffset" style="width: 10px;"></div>
<div class="mktoFieldWrap"><label for="LastName" id="LblLastName" class="mktoLabel mktoHasWidth" style="width: 100px;">
<div class="mktoAsterix">*</div>Last Name:
</label>
<div class="mktoGutter mktoHasWidth" style="width: 10px;"></div><input id="LastName" name="LastName" maxlength="255" aria-labelledby="LblLastName InstructLastName" type="text" class="mktoField mktoTextField mktoHasWidth"
style="width: 150px;"><span id="InstructLastName" tabindex="-1" class="mktoInstruction"></span>
<div class="mktoClear"></div>
</div>
<div class="mktoClear"></div>
</div>
<div class="mktoClear"></div>
</div>
<div class="mktoFormRow">
<div class="mktoFieldDescriptor mktoFormCol" style="margin-bottom: 10px;">
<div class="mktoOffset" style="width: 10px;"></div>
<div class="mktoFieldWrap"><label for="Email" id="LblEmail" class="mktoLabel mktoHasWidth" style="width: 100px;">
<div class="mktoAsterix">*</div>Email Address:
</label>
<div class="mktoGutter mktoHasWidth" style="width: 10px;"></div><input id="Email" name="Email" maxlength="255" aria-labelledby="LblEmail InstructEmail" type="email" class="mktoField mktoEmailField mktoHasWidth" style="width: 150px;"><span
id="InstructEmail" tabindex="-1" class="mktoInstruction"></span>
<div class="mktoClear"></div>
</div>
<div class="mktoClear"></div>
</div>
<div class="mktoClear"></div>
</div>
<div class="mktoButtonRow"><span class="mktoButtonWrap mktoSimple" style="margin-left: 120px;"><button type="submit" class="mktoButton">Submit</button></span></div><input type="hidden" name="formid" class="mktoField mktoFieldDescriptor"
value="1107"><input type="hidden" name="munchkinId" class="mktoField mktoFieldDescriptor" value="740-LKM-263">
</form>
<form style="display: none; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(51, 51, 51); visibility: hidden; position: absolute; top: -500px; left: -1000px; width: 1600px;" novalidate="novalidate"
class="mktoForm mktoHasWidth mktoLayoutLeft"></form>
Text Content
ADVISORY BOARDS AREN’T ONLY FOR EXECUTIVES. JOIN THE LOGROCKET CONTENT ADVISORY BOARD TODAY → * Blog DevProduct ManagementUX DesignPodcast * Features * Solutions Solve User-Reported IssuesFind Issues FasterOptimize Conversion and Adoption * Sign In * Start monitoring for free Share * * * Reply * 1 Overwhelmed by noisy JavaScript errors? Discover impactful frontend errors with LogRocket Galileo LEARN MORE Nwose Lotanna Follow Web Developer and Writer TYPESCRIPT ENUMS VS. TYPES: ENHANCING CODE READABILITY June 16, 2023 9 min read 2741 SEE HOW LOGROCKET'S AI-POWERED ERROR TRACKING WORKS NO SIGNUP REQUIRED Check it out close this ✕ Editor’s note: This guide to TypeScript enums vs. types was last updated by Oyinkansola Awosan on 16 June 2023 to reflect recent changes to TypeScript. This update also includes new sections on extracting the object type of enums and converting enums to arrays. To learn more about enums, check out our guide to extending enums in TypeScript. TypeScript (as you probably already know) is an open source, strongly typed, object-oriented compiled language developed and maintained by the team at Microsoft. It is a superset of JavaScript with static typing options. It is designed to develop large and scalable applications that compile to JavaScript. Writing readable code is important. TypeScript types and enums contribute to code readability by providing clear and expressive ways to describe and work with data in TypeScript. In this article, we will be exploring how both work, why, and how to use them. Jump ahead: * What are enums and types? * Why use enums? * When to use enums * When to avoid enums * Types of TypeScript enums * Numeric enums * Custom numeric enums * Computed enums * Const enums * String enums * Heterogeneous enums * Using enums for reverse mapping * Extracting object types of enums * How to convert an enum to an array * TypeScript enums vs. alternatives WHAT ARE ENUMS AND TYPES? In most object-oriented programming languages like C, C#, and Java, there is a data type we know as enumerations — enums for short. Java enums are a special kind of Java class used to define collections of constants. JavaScript, however, does not have the enum data type, but they‘ve been available in TypeScript since v2.4. Enums allow us to define or declare a collection of related values that can be numbers or strings as a set of named constants. Unlike some types available in TypeScript, enums are preprocessed and not tested at compile time or runtime. Enums are defined with the enum keyword, like this: enum Continents { North_America, South_America, Africa, Asia, Europe, Antartica, Australia } // usage var region = Continents.Africa; In TypeScript, the type system refers to the various types of values the language accepts. A type refers to a value’s properties and functions; this means that every value in TypeScript has a type. The type system validates the values given before the program stores them. The TypeScript compiler uses types to analyze your code and hunts for errors and bugs. Types are definitions of data types. This means a type of data is defined by its type. There are different types in TypeScript. Some common ones include: * Primitive types * Union types * Tuples * Arrays * Advanced types WHY USE ENUMS? Enums are just one useful way to organize code in TypeScript. With enums, you can create constants that you can easily relate to, making constants more legible. Enums also allow developers the freedom to create memory-efficient custom constants in JavaScript. As we know, JavaScript does not support enums, but TypeScript helps us access them. As mentioned, TypeScript enums save runtime and compile time with inline code in JavaScript (which we will see later in this article). And lastly, TypeScript enums also provide a certain flexibility that we previously had only in languages like Java. This flexibility makes it easy to express and document our intentions and use cases easily. WHEN TO USE ENUMS You should use enum types whenever you need to represent a fixed set of constants. That includes enum types such as the planets in our solar system and data sets where you know all possible values at compile time — for example, the choices on a menu, command line flags, etc. This means that enums should ideally be used in situations where there are distinct values that can be seen as constants, like seven days of the week and the other examples given above: enum Days { Sunday = 1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } Enums can be used inside array initializations just as other TypeScript data types. Here’s a quick example: enum NigerianLanguage { Igbo, Hause, Yoruba } //can be used in array initialisation let citizen = { Name: 'Ugwunna', Age: 75, Language: NigerianLanguage.Igbo } Enums can also be used where strings or constants need to be represented in a variable. WHEN TO AVOID ENUMS TypeScript enums can be great to use, but there are scenarios where they are unnecessary. However, some developers tend to overlook these scenarios and go ahead to use them, which is not a great practice. Enums are best suited for representing a fixed set of values. If you intend to reassign or change the enum member values, it is important to remember that enums are type-safe and, therefore, would return compile errors on reassignment. If you anticipate that the values will need to be dynamically generated at runtime, use constants or other data structures that may be more appropriate. Enum values are usually defined upfront, and defining and managing a long list of constants within an enum can become cumbersome. As a result of this, enums should be avoided when working with large or open-ended sets of values. Using an enum may not be the best choice if the values to be represented are from an external data source. Enums are primarily designed for compile-time constants and may not easily synchronize with external data sources. It is important to remember that the general idea behind enums was to help create a user-defined constants system. -------------------------------------------------------------------------------- OVER 200K DEVELOPERS USE LOGROCKET TO CREATE BETTER DIGITAL EXPERIENCES Learn more → -------------------------------------------------------------------------------- TYPES OF TYPESCRIPT ENUMS TypeScript enums are a way to define a set of named constants. They allow you to create a collection of related values that can be assigned to variables or used as a type. Enums provide a convenient way to work with a fixed set of values in a type-safe manner. By default, enums will initialize the first value to 0 and add 1 to each additional value. There are three types of TypeScript enums, namely: * Numeric enums * String enums * Heterogeneous enums NUMERIC ENUMS By default, TypeScript enums are number-based. This means they can store string values as numbers. Numbers, and any other type that is compatible with them, can be assigned to an instance of the enum. Let’s say we want to store the days of the weekend. The representing enum in TypeScript can look something like this: enum Weekend { Friday, Saturday, Sunday } In the code block above, we have an enum we call Weekend. The enum has three values: Friday, Saturday, and Sunday. In TypeScript, like in other languages, enum values start from zero and increase by one for each member. They will be stored like this: Friday = 0 Saturday = 1 Sunday = 2 We see that enums are always assigned numbers for storage; the value always takes the numeric value of zero, although we can customize the storage values with our own logic. CUSTOM NUMERIC ENUMS In TypeScript, we can dictate the first numeric value of our enumerations. Using the weekend days example above, we can initialize the first numeric value like this: enum Weekend { Friday = 1, Saturday, Sunday } The above code block will store Friday as 1, Saturday as 2, and Sunday as 3. If we add a number to the first member, we still get sequential incrementation by one for the rest of the members. However, we have the power to dictate that we do not want a sequential trail by giving them any numerical value. The code block below is semantic and works in TypeScript: enum Weekend { Friday = 1, Saturday = 13, Sunday = 5 } Just like other data types in TypeScript, we can use enums as function parameters or return types, like this: enum Weekend { Friday = 1, Saturday, Sunday } function getDate(Day: string): Weekend { if ( Day === 'TGIF') { return Weekend.Friday; } } let DayType: Weekend = getDate('TGIF'); We declared a Weekend enum above. We then declared a getDate function that takes the input Day, which returns a Weekend enum. In the function, we check for some condition that now returns an enum member. COMPUTED ENUMS The value of a numeric enum can either be constant or evaluated, just like any other number data type in TypeScript. You can define or initialize your numeric enum with a computed value: enum Weekend { Friday = 1, Saturday = getDate('TGIF'), Sunday = Saturday * 40 } function getDate(day : string): number { if (day === 'TGIF') { return 3; } } Weekend.Saturday; // returns 3 Weekend.Sunday; // returns 120 When enums include a mixture of computed and constant members, the enum members that are not initialized either come first or must come after other initialized members with numeric constants. Ignoring this rule above results in an initializer error; remember to rearrange the enum members accordingly if you see that. CONST ENUMS If you want to boost the performance of your numeric enums, you can declare them as a constant. Let’s use our weekend example to illustrate: enum Weekend { Friday = 1, Saturday, Sunday } var day = Weekend.Saturday; When compiled to JavaScript, the runtime looks up Weekend and looks up Weekend.Saturday at execution. For optimal performance at runtime, you can make the enum a constant instead, like this: const enum Weekend { Friday = 1, Saturday, Sunday } var day = Weekend.Saturday; The JavaScript generated at compile with the constant is: var day = 2; We see how the compiler just inlines the enum usages and does not even bother generating JavaScript for enum declarations when it sees the const. It is important to be aware of this choice and the consequences that may result when you have use cases that require number-to-strings or strings-to-number lookups. You can also pass the compiler flag preserveConstEnums, and it will still generate the Weekend definition. STRING ENUMS So far, we have only looked at numeric enums, wherein the member values are numbers. In TypeScript, your enum members can also be string values. String enums are vital and easy to deal with for the purpose of readability during error logging and debugging because of their meaningful string values. Refer to the following code: enum Weekend { Friday = 'FRIDAY', Saturday = 'SATURDAY', Sunday = 'SUNDAY' } It can then be used to compare strings in conditional statements like this: enum Weekend { Friday = 'FRIDAY', Saturday = 'SATURDAY', Sunday ='SUNDAY' } const value = someString as Weekend; if (value === Weekend.Friday || value === Weekend.Sunday){ console.log('You choose a weekend'); console.log(value); } In the example above, we have defined a string enum, Weekend, just like the numeric enum we had above, but this time with the enum values as strings. The obvious difference between numeric and string enums is that numeric enum values are mostly sequentially incremented automatically, while string enum values are not incremented; rather, each value is initialized independently. HETEROGENEOUS ENUMS TypeScript also allows for a mixture of strings and numbers, called heterogeneous enum. In this type of enum, we can assign numeric and string values to its members. This type of enum is used sparingly as it has few applications and is more limited. Refer to this example: enum Weekend { Friday = 'FRIDAY', Saturday = 1, Sunday = 2 } Although this is possible, the range of scenarios that will likely require this use case is small. So, unless we are trying to take advantage of JavaScript’s runtime behavior in a clever way, it is advised that we do not use heterogenous enums. USING ENUMS FOR REVERSE MAPPING TypeScript enums support reverse mapping, which simply means that just as we have access to the value of an enum member, we also have access to the enum name itself. We’ll use a sample of our first demonstration to portray this: enum Weekend { Friday = 1, Saturday, Sunday } Weekend.Saturday Weekend["Saturday"]; Weekend[2]; In the code block above, Weekend.Saturday will return 2, and then Weekend["Saturday"] will also return 2. Interestingly, however, due to reverse mapping, Weekend[2] will return its member name Saturday. We can see a simple way TypeScript interprets reverse mapping with a log command: enum Weekend { Friday = 1, Saturday, Sunday } console.log(Weekend); If you run this in a console, you will see this output: { '1': 'Friday', '2': 'Saturday', '3': 'Sunday', Friday : 1, Saturday : 2, Sunday : 3 } The objects contain the enums appearing both as values and as names, just as TypeScript intended. This shows the potency of reverse mapping in TypeScript. EXTRACTING OBJECT TYPES OF ENUMS To extract the object types of enums in TypeScript, you can use the keyofoperator in combination with the enum itself. Here’s an example: enum Color { Red = 'RED', Green = 'GREEN', Blue = 'BLUE', } type ColorKey = keyof typeof Color; // 'Red' | 'Green' | 'Blue' type ColorValue = typeof Color[ColorKey]; // 'RED' | 'GREEN' | 'BLUE' const colorKey: ColorKey = 'Red'; const colorValue: ColorValue = Color[colorKey]; console.log(colorKey); // Output: 'Red' console.log(colorValue); // Output: 'RED' In this example, the keyof typeof Color expression extracts the keys of the Color enum: Red, Green, and Blue. The resulting type is ColorKey, a union type of the keys Red, Green, and Blue. The typeof Color[ColorKey] expression accesses the values of the Color enum using the extracted keys. This results in the type ColorValue, a union type of RED, GREEN, and BLUE. You can then use the ColorKey type to declare variables that can hold enum keys and the ColorValue type to declare variables that can hold enum values. In the example, colorKey is assigned the value Red, which is a valid key of the Color enum. Similarly, colorValue is assigned the corresponding value of RED. The outputs of console.log(colorKey) and console.log(colorValue) are Red and RED, respectively. HOW TO CONVERT AN ENUM TO AN ARRAY To transform a numeric enum into an array, there are two options available in TypeScript: * Object.values function * Object.keys function Using the Object.values function would look like what we have below: enum Colors { Red, Blue, Yellow } console.log(Object.values(Color).filter((v) => isNaN(Number(v))) ); TYPESCRIPT ENUMS BEST PRACTICES There are certain use cases where it’s optimal and efficient to use enums. There are also instances when you should put the enums away. Below, we’ll discuss TypeScript enums best practices. When working with a language and its concepts, following the best practices to ensure clean and maintainable code is essential. For TypeScript enums, here are some recommended best practices: * Capitalize enum names: When naming enums, one should follow the convention of using uppercase letters. For example, enum Animal is preferred over enum animal * Use string enums: If possible, use string enums instead of numeric enums. String enums are more readable, making the code easier to understand as they are more descriptive. They also help to avoid issues when members are modified or reordered. For numeric-based values or bitwise operations, use numeric enums * Assign values explicitly: When defining them, it is essential to assign values to enums explicitly. This helps to avoid unexpected behaviors and maintain consistency across different environments * Avoid automatic enum value assignment: TypeScript automatically assigns numeric values to enum members if not explicitly assigned. It is recommended to deactivate this by specifying a value for each enum. This prevents unintended changes to the enum when modifying or reordering its members By following these best practices, you can ensure that your TypeScript enums are well-defined and maintainable and enhance the overall readability of your code. TYPESCRIPT ENUMS VS. ALTERNATIVES Depending on your use case, there are some alternatives to TypeScript enums that you can use. Some of them include the union of string literals types and the as const. A union of string literals is a type that represents a specific set of string values. It allows you to define a type that can only accept one of the specified string literals, providing a more restrictive and specific type constraint. Using a union of string literals, TypeScript performs static type checking and ensures that only the specified string literals are allowed for variables of the declared type. This improves type safety and eliminates potential runtime errors caused by assigning invalid values. The as const assertion is applicable when you want to ensure that values or expressions are treated as immutable and their types are narrowed down to their literal representations. This can provide additional type safety and enable TypeScript to perform more accurate type inference. as const lets you generate your types from your data. CONCLUSION We have been able to take a good look at enums in TypeScript, including their types and properties. We also saw the syntax and practical examples of how they are used. We saw other important enums aspects like constants in enums, computed enums, and even reverse mapping. It is noteworthy that for string enums, reverse mapping is not supported. Also, for the heterogeneous ones, it is only supported for numeric type members but not for string type members. Happy coding! Further reading: LOGROCKET: FULL VISIBILITY INTO YOUR WEB AND MOBILE APPS LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps. Try it for free. * TypeScript official documentation * A quick and complete guide to TypeScript types * Types vs. interfaces in TypeScript * Put the TypeScript enums and Booleans away SHARE THIS: * Twitter * Reddit * LinkedIn * Facebook * Nwose Lotanna Follow Web Developer and Writer * Uncategorized * #typescript « How to organize your Rust tests A guide to native routing in Expo for React Native » STOP GUESSING ABOUT YOUR DIGITAL EXPERIENCE WITH LOGROCKET Get started for free BEST HEADLESS UI LIBRARIES IN REACT NATIVE Hussain Arif Sep 28, 2023 6 min read USING REACT-ARBORIST TO CREATE TREE COMPONENTS FOR REACT Ibadehin Mojeed Sep 28, 2023 13 min read LEADER SPOTLIGHT: GETTING STUFF DONE WITH RICH LAU Jessica Srinivas Sep 28, 2023 7 min read ONE REPLY TO “TYPESCRIPT ENUMS VS. TYPES: ENHANCING CODE READABILITY” 1. Kasaija Ronald says: May 11, 2021 at 5:17 am Good stuff bro LEAVE A REPLYCANCEL REPLY Does something seem off? Email support@logrocket.com X Understand everything about your customers' experience Watch "video" playback of user sessions to understand user frustration Surface errors and issues that are having the greatest impact on customers Build funnels and understand user paths with product analytics Trusted by thousands of leading companies Sign Up Sign up with GitHub Sign up with Google Sign up with Microsoft Account or By signing up, you agree to our terms of service and privacy policy. Sign Up × Would you be interested in joining LogRocket's developer community? Yeah No thanks * First Name: * Last Name: * Email Address: Submit