<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cameron McHenry</title>
    <description>The latest articles on DEV Community by Cameron McHenry (@camchenry).</description>
    <link>https://dev.to/camchenry</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F721313%2F74237300-44f2-48a4-bd10-ad3d9a88f54c.jpg</url>
      <title>DEV Community: Cameron McHenry</title>
      <link>https://dev.to/camchenry</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/camchenry"/>
    <language>en</language>
    <item>
      <title>The Difference Between TypeScript Unions, Enums, and Objects</title>
      <dc:creator>Cameron McHenry</dc:creator>
      <pubDate>Sun, 01 May 2022 17:42:07 +0000</pubDate>
      <link>https://dev.to/camchenry/the-difference-between-typescript-unions-enums-and-objects-5e3e</link>
      <guid>https://dev.to/camchenry/the-difference-between-typescript-unions-enums-and-objects-5e3e</guid>
      <description>&lt;p&gt;This article was originally posted on my blog: &lt;a href="https://camchenry.com/blog/typescript-union-vs-enum-vs-object"&gt;https://camchenry.com/blog/typescript-union-vs-enum-vs-object&lt;/a&gt;. &lt;/p&gt;




&lt;p&gt;When you first encounter unions and enums in TypeScript, you might wonder what the difference is between them. At first glance, they are very similar, but in fact they are quite different. The situation becomes even more complicated when we consider "constant objects" which are essentially another way to implement an enumeration.&lt;/p&gt;

&lt;p&gt;In this article we'll look at their similarities and differences, and when you might want to use each of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are TypeScript unions?
&lt;/h2&gt;

&lt;p&gt;I've already written a comprehensive article on &lt;a href="//./typescript-union-type"&gt;everything you need to know about union types&lt;/a&gt;. In short, union types are a way of modeling a discrete set of mutually exclusive types, or more simply put: unions model choices, where &lt;em&gt;only one choice can be made&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Union types are great because choices are &lt;em&gt;everywhere&lt;/em&gt; in the real world, so they are a powerful tool to allow TypeScript to programmatically reason about all possibilities that could result from different decisions.&lt;/p&gt;

&lt;p&gt;This means that our code will be safer automatically because &lt;strong&gt;TypeScript does all of the hard work of checking every possibility for us&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are TypeScript enums?
&lt;/h2&gt;

&lt;p&gt;Enums, short for enumerations, are a more traditional programming language feature in imperative languages like C/C++ and Java. Their purpose is similar to union types, except they act on a much more basic principle.&lt;/p&gt;

&lt;p&gt;Enums give values (strings and numbers) a human-readable name that can be referenced easily in code via the name for the enumeration.&lt;/p&gt;

&lt;p&gt;Enums were added to TypeScript in anticipation of them becoming a standard JavaScript feature, however that currently seems unlikely based on the 4 year old &lt;a href="https://github.com/rbuckton/proposal-enum"&gt;TC39 enum proposal&lt;/a&gt; still being stuck at Stage 0.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript enum example
&lt;/h3&gt;

&lt;p&gt;To make this more clear, let's look at a simple example of an enum. Suppose that we are building an application that models the days of the week as numbers (0 through 6). Instead of needing to remember what the number for each day of the week is, we can create an enum that stores that information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Monday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Tuesday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Wednesday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Thursday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Friday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Saturday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Sunday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, instead of needing to type the numbers each time, we can use the enum instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isWeekend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Saturday&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Sunday&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using enums in this case makes our code easier to read and prevents simple typos.&lt;/p&gt;

&lt;h4&gt;
  
  
  Constant enums
&lt;/h4&gt;

&lt;p&gt;It is also possible to define an &lt;code&gt;enum&lt;/code&gt; as a &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html#const-enums"&gt;&lt;code&gt;const enum&lt;/code&gt;&lt;/a&gt; similar to the constant objects which we will talk about in this article. However, using &lt;code&gt;const enums&lt;/code&gt; comes with some &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html#const-enum-pitfalls"&gt;pitfalls/caveats&lt;/a&gt; which make them slightly more difficult to use in some cases. They don't offer a significant advantage over constant objects, so we won't discuss them in more detail here, but check out the &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html#const-enums"&gt;TypeScript documentation on &lt;code&gt;const enums&lt;/code&gt;&lt;/a&gt; for more info.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are TypeScript constant objects?
&lt;/h2&gt;

&lt;p&gt;A constant object is no different from any other object in JavaScript, but when defined as &lt;code&gt;const&lt;/code&gt; in TypeScript, it becomes a much stricter type. To create a constant object, we simply define an object and then add &lt;code&gt;as const&lt;/code&gt; to make it a constant object.&lt;/p&gt;

&lt;p&gt;Making it constant makes it act similar to enum, and it can be used in almost the same way. Let's look at the previous &lt;code&gt;enum&lt;/code&gt; example, but now using an object with &lt;code&gt;as const&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Monday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Tuesday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Wednesday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Thursday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Friday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Saturday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Sunday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;as const&lt;/code&gt; makes all of the properties &lt;code&gt;readonly&lt;/code&gt;, so the values are not allowed to be changed in the type system. So, all of the keys and values are guaranteed to never change as long as we abide by the type system, just like an &lt;code&gt;enum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we are a little bit familiar with unions, enums, and constant objects, let's compare them with each other and see how they stack up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison between unions, enums, and constant objects
&lt;/h2&gt;

&lt;p&gt;To help you decide whether to use a union, enum, or object, I've created a table that summarizes the key similarities and differences:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Unions&lt;/th&gt;
&lt;th&gt;Enums&lt;/th&gt;
&lt;th&gt;Constant objects&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Strictly typed&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;🟡 Partial&lt;sup&gt;1&lt;/sup&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Available at compile-time&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Available at run-time&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Named values&lt;/td&gt;
&lt;td&gt;🟡 Partial&lt;sup&gt;2&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unique values&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sub-typing&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;🟡 Partial&lt;sup&gt;3&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;🟡 Partial&lt;sup&gt;3&lt;/sup&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mixed types&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;🟡 Partial&lt;sup&gt;4&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Computed values&lt;/td&gt;
&lt;td&gt;🟡 Partial&lt;sup&gt;5&lt;/sup&gt;
&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reverse mappings&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;1) Constant objects cannot be used directly as types, but it is simple to create a type of the key values:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ConstantObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;2) Unions can emulate named values when the values are strings, by making the value the same as the name. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Dimension&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="nx"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="nx"&gt;Z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="c1"&gt;// can be written as:&lt;/span&gt;
   &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Dimension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;3) Only keys can be easily derived, the values are not possible to subtype.&lt;/li&gt;
&lt;li&gt;4) Enums do not support mixed types within each state other than strings and numbers, such as objects, booleans, etc. (For example: you cannot use an enum to refer to an object value, even if it is constant.)&lt;/li&gt;
&lt;li&gt;5) Unions allow strings to be interpolated into them, but the interpolation will be interpreted as a &lt;a href="https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html"&gt;template literal type&lt;/a&gt;. If the interpolated value is a union, multiple possibilities will be generated. If the interpolated value is a string, only one possibility will be generated.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Unions, enums, and constant objects all support type safety
&lt;/h2&gt;

&lt;p&gt;Regardless of which language feature you choose, the one thing they share in common is static type safety. We can create additional types that derive from a union, enum, or object. This helps us lean into leveraging the full power of the TypeScript compiler and make our code safer and reduce the amount of work a developer needs to do.&lt;/p&gt;

&lt;p&gt;Another advantage of using these features over a more generic type like &lt;code&gt;string&lt;/code&gt; is that the number of possible values is much lower and is enforced by the compiler. Rather than allowing &lt;em&gt;all&lt;/em&gt; strings or &lt;em&gt;all&lt;/em&gt; numbers, we can reduce it to just a &lt;em&gt;few&lt;/em&gt; strings or a &lt;em&gt;few&lt;/em&gt; numbers.&lt;/p&gt;

&lt;p&gt;The TypeScript compiler ensures that we cannot make any spelling mistakes in values because all of the possibilities are known. Using &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;number&lt;/code&gt; does not provide the same guarantees. So, unions and enums help make the code safer by automatically preventing simple typing mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's similar between enums and constant objects
&lt;/h2&gt;

&lt;p&gt;Enums are constant objects are very similar, and so they are many properties in common:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐️ &lt;strong&gt;Run-time usable&lt;/strong&gt;: Enums and objects can be used while the program is running (for example, to build a selection menu UI)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Named values&lt;/strong&gt;: Both can give given names or aliases to specific values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No uniqueness&lt;/strong&gt;: Both do &lt;em&gt;not&lt;/em&gt; enforce uniqueness of values. There may be duplicate values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partial sub-typing&lt;/strong&gt;: Both only support sub-typing on the keys, not the values.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Both: named values
&lt;/h3&gt;

&lt;p&gt;Another unique advantage of enums and objects is that keys and values can be named independently. This is great for improving the readability of code, essentially creating two sets: human-readable names, and machine-readable values.&lt;/p&gt;

&lt;p&gt;This is good if you don't control the values, but want to give them understandable names. For example, using an enum or object to identify pin numbers for microchips:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Power&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;LED0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;LED1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Button1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Button2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Ground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Power&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;LED0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;LED1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Button1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Button2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Ground&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the advantages of using an enum or object instead of a union type, because union types cannot be referred to by name, only by their value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Both: run-time usability
&lt;/h3&gt;

&lt;p&gt;The biggest advantage of using an enum is that they exist even after code is compiled, while the program is running. This is because enums are ultimately generated as normal JavaScript objects.&lt;/p&gt;

&lt;p&gt;This can be helpful when it is necessary to have the benefits of type safety and compile time, while also remembering the set of values while the program is running.&lt;/p&gt;

&lt;p&gt;Union types cannot be used as values, and cannot be used in executable code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Note: `Color` does not exist at run-time, so we&lt;/span&gt;
&lt;span class="c1"&gt;// cannot do something like this:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;//                        ^^^^^ ERROR: 'Color' only refers&lt;/span&gt;
&lt;span class="c1"&gt;// to a type, but is being used as a value here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, an &lt;code&gt;enum&lt;/code&gt; is essentially an alias for a JavaScript object. It is both a type and a value at the same time, similar to how a class can act as both a type and an actual value in JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Green&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Or:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Note: `Color` _does_ exist as an actual value at run-time,&lt;/span&gt;
&lt;span class="c1"&gt;// so we can use it just like any object:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; ["Red", "Green", "Blue"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages of union types
&lt;/h2&gt;

&lt;p&gt;There are several advantages to using union types in TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unique values&lt;/strong&gt;: Unions automatically simplify values to be unique&lt;/li&gt;
&lt;li&gt;⭐️ &lt;strong&gt;Mixed types&lt;/strong&gt;: Unions can represent more kinds of types like objects, arrays, booleans, and so on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sub-typing&lt;/strong&gt;: Unions support creating subtypes easily&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Computed types&lt;/strong&gt;: Unions have partial support for dynamic values, limited to the possibilities of template literal types.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Union advantage: unique values
&lt;/h3&gt;

&lt;p&gt;Unlike enums, values in a union represent a set, which is a collection of unique values. So, if any values are repeated, then they will only appear once in the resulting type. For example, &lt;code&gt;type N = 1 | 2 | 3 | 1 | 2 | 3&lt;/code&gt; simplifies to just &lt;code&gt;N = 1 | 2 | 3&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Union advantage: mixed types
&lt;/h3&gt;

&lt;p&gt;One of the most important properties of unions is that they can contain all different kinds of types, not just strings and numbers. For example, this is a perfectly valid union which would be impossible to represent with an enum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SomeUnionOfTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this is a string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;this_is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;an object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// object&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// array (object)&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using many different kinds of types brings some challenges, such as how to differentiate between them. To learn more on how to differentiate between types in a union, check out my complete guide on &lt;a href="//./typescript-type-guards"&gt;TypeScript type guards&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Union advantage: sub-typing
&lt;/h3&gt;

&lt;p&gt;Another great benefit of union types is that they can be easily transformed into other types. For example, we can use union types to generate a large set of possible values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bottom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Property&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;margin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;padding&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "margin-top" | "margin-right" | "margin-left"&lt;/span&gt;
&lt;span class="c1"&gt;//  | "margin-bottom" | "padding-top" | "padding-right"&lt;/span&gt;
&lt;span class="c1"&gt;//  | "padding-left" | "padding-bottom"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or values can be narrowed down to just a subset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bottom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;VerticalDirection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Pick&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bottom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;HorizontalDirection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VerticalDirection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Union advantage: computed types
&lt;/h3&gt;

&lt;p&gt;Neither enums nor unions have full support for dynamic values, but unions do have some partial support for dynamic value in the form of template literal types. Values can be interpolated in to a union, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ColorDeclaration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "color: red;" | "color: green;" | "color: blue;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To some degree, types can be interpolated in even if they are dynamic also, but little inference is possible, so type safety is somewhat limited:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NamedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;NamedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Declaration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; `color: ${string};`;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the dynamic input eliminates the previous type safety that was given by knowing all of the possible values. On the other hand, this does allow us to represent dynamic values to at least some degree.&lt;/p&gt;

&lt;p&gt;Enums do not support computed values or computed keys, so this is a uniquely union type advantage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unique advantage of enums: reverse mapping
&lt;/h2&gt;

&lt;p&gt;The main advantage that enums have over unions and constant objects is that the values are automatically mapped to their names, as well as the reverse: names can be mapped to values. This can be useful when it is necessary to often go between the names and values often. For example, let's use the &lt;code&gt;Pin&lt;/code&gt; enum from before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Power&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;LED0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;LED1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Button1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Button2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Ground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can easily answer two questions with the &lt;code&gt;enum&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the purpose of pin &lt;code&gt;0&lt;/code&gt;?
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;purpose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; "Power"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;What pin number corresponds to &lt;code&gt;Ground&lt;/code&gt;?
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ground&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Ground&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, two things diminish the usefulness of this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This feature can be replicated with objects when it is needed.&lt;/li&gt;
&lt;li&gt;If we don't need the reverse mapping, this results in useless code being generated. This can bloat the JavaScript bundle size significantly depending on how many enums are used in a project.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Unique advantage of constant objects: computed values
&lt;/h2&gt;

&lt;p&gt;One unique advantage of constant objects that can be helpful in some circumstances is that it is possible to used computed values as keys or values. For example, suppose we have an object which resolves theme values for whether we should show a light or dark-mode color scheme. In addition to the base keys and values, we can also create other dynamically computed values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultColorScheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightAlias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;day&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;darkAlias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;night&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ColorScheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;defaultColorScheme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lightAlias&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;darkAlias&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We still retain the type safety of saying &lt;code&gt;ColorScheme.light&lt;/code&gt; or &lt;code&gt;ColorScheme.dark&lt;/code&gt; but can also use it in dynamic circumstances to find &lt;code&gt;ColorScheme.default&lt;/code&gt; or &lt;code&gt;ColorScheme[usedSpecifiedTheme]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the type that TypeScript ultimately resolves for this object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ColorScheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not perfect, but at least it is possible to use computed values if necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  What type should I use?
&lt;/h2&gt;

&lt;p&gt;We've looked at a lot of examples and caveats of unions, enums, and objects. So, let's wrap things up by looking at a subjective opinion of what type I recommend you should use depending on the circumstances.&lt;/p&gt;

&lt;p&gt;If you just want a quick summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use union types as a default&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use constant objects for run-time purposes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid using &lt;code&gt;enum&lt;/code&gt; if possible&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When should you use a union in TypeScript
&lt;/h3&gt;

&lt;p&gt;As a general guide, union types might be a good choice to use if many of the following apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a known set of possible values&lt;/li&gt;
&lt;li&gt;The values are self-descriptive&lt;/li&gt;
&lt;li&gt;All of the values must be unique&lt;/li&gt;
&lt;li&gt;The values are only needed at compile-time (i.e., not used in the output)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When should you use a constant object in TypeScript
&lt;/h3&gt;

&lt;p&gt;Constant objects could be a good choice if several of the following apply to the situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a known set of possible values&lt;/li&gt;
&lt;li&gt;The values don't correspond to their name&lt;/li&gt;
&lt;li&gt;The values are used in the output (for example, a selection menu or printed to the screen)&lt;/li&gt;
&lt;li&gt;The keys or values can be dynamic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When should you use an enum in TypeScript: probably never
&lt;/h3&gt;

&lt;p&gt;Besides automatically doing reverse mapping (which can actually be a disadvantage), there are not enough benefits to justify using an enum over a constant object. Using a constant object over an enum will result in a smaller bundle size, and more flexibility with being able to use dynamic values and interoperate with standard JavaScript syntax.&lt;/p&gt;

&lt;p&gt;Enums were added to TypeScript in anticipation of them becoming a standard JavaScript feature, however it seems extremely unlikely that will happen anytime soon, or ever (see: &lt;a href="https://github.com/rbuckton/proposal-enum"&gt;TC39 proposal&lt;/a&gt;). As such, they have not seen many language improvements in the last few years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully this guide helped clear up the confusion between enums and unions, and made the advantages and disadvantages between enums, unions, and constant objects clear. However, enums are somewhat lackluster when compared to the other two, and probably should not be used in most cases. On the other hand, unions and constant objects work together very well and can be used together, or independently, in a broad set of situations to implement mutual exclusivity in TypeScript programs.&lt;/p&gt;

&lt;p&gt;Good luck and happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Serverless Saved Money on My Heating Bill</title>
      <dc:creator>Cameron McHenry</dc:creator>
      <pubDate>Wed, 05 Jan 2022 15:00:11 +0000</pubDate>
      <link>https://dev.to/camchenry/how-serverless-saved-money-on-my-heating-bill-2m4o</link>
      <guid>https://dev.to/camchenry/how-serverless-saved-money-on-my-heating-bill-2m4o</guid>
      <description>&lt;p&gt;This post was originally published on &lt;a href="https://camchenry.com/blog/how-serverless-saved-my-heating-bill" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Currently, it's winter in the Northeastern United States, where I live. That means it gets uncomfortably cold outside. That means one big thing for everyone living here: figuring out how to keep our homes warm without literally burning money.&lt;/p&gt;

&lt;p&gt;Where I live, the only viable heating option right now is burning propane.&lt;/p&gt;

&lt;p&gt;Unfortunately, propane is more expensive now in the US than it has been at any time in the past 5 years.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Naturally, this meant that I wanted to save some money on my heating bill this year, if possible. The only way to do that is to reduce the amount of propane I burned by reducing the amount of heat I need to produce.&lt;/p&gt;

&lt;p&gt;The problem is that I can't measure how much heat I need to produce, &lt;strong&gt;I can only measure how much propane I have used.&lt;/strong&gt; The company that supplies propane to us provides a dashboard where I can check how much propane is in the tank.&lt;/p&gt;

&lt;p&gt;Sadly, the dashboard only shows the &lt;em&gt;current&lt;/em&gt; level of propane in the tank, but doesn't show the propane used per day, or any sort of historical data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's hard to improve what isn't measured&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, to know whether more insulation or other efficiency improvements are actually saving money, I needed to start tracking the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;When faced with a problem, I did what any software engineer would do: build a full-stack web application deployed to the edge using the hottest JavaScript framework.&lt;/p&gt;

&lt;p&gt;The idea was to build a web application to periodically scrape the current level of propane in the tank, then store that in a database, and use the stored information to compute consumption rate and display historical data.&lt;/p&gt;

&lt;p&gt;That meant I needed to pick:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a scraping tool (for fetching the current gas level)&lt;/li&gt;
&lt;li&gt;a database (for storing the data)&lt;/li&gt;
&lt;li&gt;a framework (for interacting with the database and rendering pages)&lt;/li&gt;
&lt;li&gt;a host (for hosting the whole application)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I decided to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scraping: &lt;a href="https://www.browserless.io/" rel="noopener noreferrer"&gt;Browserless&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Database: &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Web framework: &lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hosting: &lt;a href="https://fly.io/" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a diagram that shows the architecture of the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlcL-zB88Cde3kVONd9dPuQ%2F43ccdeae-066d-4d9f-38ce-fc542f4c7c00%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlcL-zB88Cde3kVONd9dPuQ%2F43ccdeae-066d-4d9f-38ce-fc542f4c7c00%2Fpublic" alt="Architecture diagram of the gas tracking application. The client interacts with the Remix application, which runs within Fly.io, via GET and POST requests to view the dashboard and fetch new data. The Remix application also interacts with the external services Browserless and Supabase to fetch the new data and store it."&gt;&lt;/a&gt;&lt;br&gt;Architecture diagram of the gas tracking application, which shows how Remix coordinates rendering pages for our client, receiving fetch requests, scraping webpages, and updating the database.
  &lt;/p&gt;

&lt;h3&gt;
  
  
  Scraping tool: Browserless
&lt;/h3&gt;

&lt;p&gt;For the scraping tool, I chose to use &lt;a href="https://www.browserless.io/" rel="noopener noreferrer"&gt;Browserless&lt;/a&gt; which I wanted to try in a real-world scenario. It's essentially Puppeteer-as-a-Service, so you don't need to worry about installing Chromium or anything. Just install the &lt;a href="https://pptr.dev/" rel="noopener noreferrer"&gt;puppeteer&lt;/a&gt; library, connect to Browserless, and start scraping.&lt;/p&gt;

&lt;p&gt;It includes 20,000 CPU seconds for free, beyond which you have to start paying, but the free allotment of CPU time was more than enough for this project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database: Supabase
&lt;/h3&gt;

&lt;p&gt;I chose to use &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; as my database, because I wanted to use PostgreSQL as the database since I like schemas and everything that SQL affords. However, I didn't want the bother of hosting the database myself, getting it set up, maintaining it, and so on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I just wanted to get a database running as quickly as possible so I could build my application. Supabase was perfect for that.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Framework: Remix
&lt;/h3&gt;

&lt;p&gt;I was an early supporter of &lt;a href="https://remix.run" rel="noopener noreferrer"&gt;Remix&lt;/a&gt;, because I think it's a great framework that has the potential to dramatically change the face of JavaScript web development. It lets you have fast server-rendered web pages without having to give up building an awesome user interface with JavaScript. There's a lot to say about it, but I'll leave that for another time.&lt;/p&gt;

&lt;p&gt;Suffice to say, &lt;strong&gt;this project probably wouldn't be possible without Remix&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remix lets me build a &lt;em&gt;true&lt;/em&gt; full-stack JavaScript application quickly and easily without having to give up the benefits of a complex client-side application, or the benefits of a server, such as querying a database, implementing authentication, and so on.&lt;/p&gt;

&lt;p&gt;These things are possible with other frameworks, but there are more limitations to where it can be deployed and what sorts of libraries can be imported, and how they can be used.&lt;/p&gt;

&lt;p&gt;For this project, Remix will orchestrate rendering the pages with React, scraping the latest data on a &lt;code&gt;POST&lt;/code&gt; request, and fetching historical data from Supabase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Host: Fly.io
&lt;/h3&gt;

&lt;p&gt;In the spirit of trying another new service, I chose to use &lt;a href="https://fly.io/" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt; as my hosting provider. It's been a great experience so far, and the &lt;a href="https://github.com/firecracker-microvm/firecracker" rel="noopener noreferrer"&gt;underlying technology&lt;/a&gt; is impressive, allowing for a secure, efficient, and fast serverless environment. This allows it to be deployed all over the world, close to where your users lives so your web application is faster.&lt;/p&gt;

&lt;p&gt;Remix also comes with a Fly.io deployment template, which means you can deploy your application anywhere in the world in just a few minutes after creating your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Putting all of these serverless services together, I was able to build my gas-tracking application over a weekend (while on a bus!) and deploy it for my own personal use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlcL-zB88Cde3kVONd9dPuQ%2F67187615-d70d-46d3-6c01-53d7da41c300%2Fpublic" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimagedelivery.net%2FlcL-zB88Cde3kVONd9dPuQ%2F67187615-d70d-46d3-6c01-53d7da41c300%2Fpublic" alt="A picture of the gas tracking dashboard, which shows various metrics like current gas level, gas consumption per day, and number of days remaining until the tank is empty. There is also a chart that shows historical gas tank data from the last month."&gt;&lt;/a&gt;&lt;br&gt;The dashboard for the gas tracking application, which helps me gauge how much heat is being used and how effectively different house work affects our heating bill.
  &lt;/p&gt;

&lt;p&gt;So far, using this application, I've been able to realize hundreds of dollars in savings on our heating bill and accurately measure how much propane is used.&lt;/p&gt;

&lt;p&gt;Something I didn't expect is that &lt;strong&gt;this project cost me nothing at all&lt;/strong&gt;, except for the time it took to develop it. The framework is free. All of the libraries I used are open source and free. The application hosting on Fly.io is free, and I got a free randomly generated &lt;code&gt;fly.dev&lt;/code&gt; domain name with HTTPS. Even the database and scraping tool are free for the amount that I use them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take-away
&lt;/h2&gt;

&lt;p&gt;Hopefully you have figured out by now that this article isn't really about how to save money on your heating bill.&lt;/p&gt;

&lt;p&gt;This is an article about how &lt;strong&gt;building a serverless application is easier and better than ever in 2022&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Edge-focused web frameworks like &lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt; make it easy to build full-stack web applications that can be deployed to hosts like &lt;a href="https://fly.io/" rel="noopener noreferrer"&gt;Fly.io&lt;/a&gt; and run anywhere in the world for free. In addition, services like &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; make it easy to build a production-ready application in a short amount of time.&lt;/p&gt;

&lt;p&gt;Now is a better time than ever to start building a website.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While there's absolutely a learning curve to getting started, once you've got momentum, modern web development feels like having rocket boosters. The distance between idea and execution is as short as it's ever been.&lt;/p&gt;
&lt;cite&gt;— Simeon Griggs, &lt;a href="https://www.simeongriggs.dev/there-has-never-been-a-better-time-to-build-websites" rel="noopener noreferrer"&gt;There has never been a better time to build a website&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even compared to a few years ago, there are far more capabilities available today to developers and at a substantially lower cost.&lt;/p&gt;

&lt;p&gt;You don't need a dedicated server. You don't need a domain name. You don't need to be an expert. You don't even have to write code!&lt;/p&gt;

&lt;p&gt;Right now is a great time to be a web developer. So let's get out there, lift each other up, and build great things!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A rising tide lifts all boats&lt;/p&gt;
&lt;/blockquote&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Source for propane price: &lt;a href="https://ycharts.com/indicators/us_residential_propane_price" rel="noopener noreferrer"&gt;https://ycharts.com/indicators/us_residential_propane_price&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>serverless</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Everything You Need To Know About TypeScript Union Types</title>
      <dc:creator>Cameron McHenry</dc:creator>
      <pubDate>Mon, 29 Nov 2021 05:22:39 +0000</pubDate>
      <link>https://dev.to/camchenry/everything-you-need-to-know-about-typescript-union-types-1h55</link>
      <guid>https://dev.to/camchenry/everything-you-need-to-know-about-typescript-union-types-1h55</guid>
      <description>&lt;p&gt;This was originally posted on my &lt;a href="https://camchenry.com/blog/typescript-union-type"&gt;blog&lt;/a&gt;. If you enjoy posts like this, consider following me at &lt;a href="https://twitter.com/cammchenry"&gt;@cammchenry&lt;/a&gt;!&lt;/p&gt;




&lt;p&gt;Programming in TypeScript is all about creating models that help us to write safe code. Among those models, union types are one of the most useful, because they allow us to model mutually exclusive states like: low, medium, or high, one or none, on or off, and so on. In this article, I'll teach you what a union type is, when to use it, and tips on how to use it effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a union type in TypeScript?
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types"&gt;union type&lt;/a&gt; (or "union" or "disjunction") is a set of types that are mutually exclusive. The type represents all of the possible types simultaneously. A union type is created with the union operator &lt;code&gt;|&lt;/code&gt;, by listing out each type and separating them with a pipe character.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Union&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The union type provides more information to the TypeScript compiler that allows it to &lt;strong&gt;prove code is safe &lt;em&gt;for all possible situations&lt;/em&gt;&lt;/strong&gt;, which is a powerful tool. We may not know whether the user will pass a &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, or &lt;code&gt;object&lt;/code&gt; (for example) to a function, but we can guarantee that every case is handled without needing to write any unit tests to check that.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should you use a union type?
&lt;/h3&gt;

&lt;p&gt;Union types are a perfect fit for a situation where we know exactly what all of the possible states are, but we don't know when we compile the program which one will be used. For example, we could use union types to store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;days of the week,&lt;/li&gt;
&lt;li&gt;color palettes,&lt;/li&gt;
&lt;li&gt;columns of a database table&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Events"&gt;DOM event names&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Finite-state_machine"&gt;finite state machine&lt;/a&gt; states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a counterexample, something like a person's name is not a good fit for a union type, because there are essentially an infinite (or very large) number of possible states.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of union types
&lt;/h3&gt;

&lt;p&gt;In the DOM, we can only store strings for values, or numbers as strings. So, the only acceptable types for a DOM value are essentially a string or a number. (This is exactly the definition of the &lt;code&gt;ReactText&lt;/code&gt; type).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Acceptable DOM values&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, DOM events are always happen independently of each other (events are processed one at a time). So, there is a finite list of possible events that can be processed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MouseEvent&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* and so on */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use a union type to represent a subset of primitive types like &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;number&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, we could write some business logic functions that only accept days of the week:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tuesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wednesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thursday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Friday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isBusinessDay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;isBusinessDay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;span class="nx"&gt;isBusinessDay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;
&lt;span class="nx"&gt;isBusinessDay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Whensday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//             ^^^^^^^^ ERROR: Argument of type '"Whensday"'&lt;/span&gt;
&lt;span class="c1"&gt;// is not assignable to parameter of type 'DayOfWeek'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;strong&gt;every type in the union is the same&lt;/strong&gt;, then we can use functions and operators as expected on those types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NumberOfColumns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getColumnWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;totalWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberOfColumns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;totalWidth&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;getColumnWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; "320.00px"&lt;/span&gt;
&lt;span class="nx"&gt;getColumnWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//                   ^^ ERROR: Argument of type '16' is not&lt;/span&gt;
&lt;span class="c1"&gt;// assignable to parameter of type 'NumberOfColumns'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the types are different (which is most of the time), then we cannot simply call functions on them or use arithmetic operators. We need to differentiate between the types in the union.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to tell which type is currently in use
&lt;/h2&gt;

&lt;p&gt;Of course, it's great that we can model mutually exclusive states with union types, but how do we actually use them? What if every type is not the same? How do we make sense of a union and figure out which specific case we have?&lt;/p&gt;

&lt;p&gt;We can differentiate between types in a union with a type guard. A &lt;strong&gt;type guard&lt;/strong&gt; is a conditional check that allows us to differentiate between types. And in this case, a type guard lets us figure out exactly which type we have within the union.&lt;/p&gt;

&lt;p&gt;There are multiple ways to do this, and it largely depends on what types are contained within the union. I cover this topic in much more detail here on my &lt;a href="https://camchenry.com/blog/typescript-type-guards"&gt;post about type guards&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;there is a shortcut to making differentiating between types in a union easy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enter discriminated unions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a discriminated union?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;discriminated union&lt;/strong&gt; (also called "distinguished union" or "tagged union") is a special case of a union type that allows us to easily differentiate between the types within it.&lt;/p&gt;

&lt;p&gt;This is accomplished by adding a field to each type that has a unique value, which can be used to differentiate between the types using an equality type guard.&lt;/p&gt;

&lt;p&gt;For example, if we had a type which represented all possible events that could occur, we could give each event a unique name. Then, we just need to check the event name to know exactly what type/case we are handling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AppEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keypress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;focus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AppEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;// We know it is a mouse click, so we can access `x` and `y` now&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Mouse clicked at (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keypress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;// We know it is a key press, so we can access `key` and `code` now&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Key pressed: (key=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, code=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;focus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;// We know it is a focus event, so we can access `element`&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Focused element: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the advantage is that we can have completely disparate types in our union, and easily handle each case with just a single &lt;code&gt;if&lt;/code&gt; check. This lends itself well to extension, because we can easily add new events and new cases to our application and lean on TypeScript to ensure that we don't forget to handle them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get a single type from a union type
&lt;/h2&gt;

&lt;p&gt;Sometimes, we want to deal with just a single type from union type, or a subset of the types. Thankfully, TypeScript provides a built-in utility type called &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union"&gt;&lt;code&gt;Extract&lt;/code&gt;&lt;/a&gt; to &lt;em&gt;extract&lt;/em&gt; a single type from a union type.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;DayOfWeek&lt;/code&gt; type from before, we can extract individual days from the type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tuesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wednesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thursday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Friday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BusinessDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tuesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wednesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thursday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Friday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday"&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Weekend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "Saturday" | "Sunday"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might seem redundant, but the advantage is that we are deriving types based on our &lt;code&gt;DayOfWeek&lt;/code&gt; type. So, if the base type ever changes, we can be sure that all of our types are still valid.&lt;/p&gt;

&lt;p&gt;But, &lt;code&gt;Extract&lt;/code&gt; is more powerful than just extracting a single type. It can extract all &lt;strong&gt;assignable types&lt;/strong&gt; from a union type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Type for a configuration value that can be defined in multiple ways:&lt;/span&gt;
&lt;span class="c1"&gt;// either as a single value (string or number), array of values, or an object.&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Only config values that are assignable to objects will have this type&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Value[] | Record&amp;lt;string, Value&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to get a subset of a union type
&lt;/h2&gt;

&lt;p&gt;We saw that &lt;code&gt;Extract&lt;/code&gt; can be used to a subset of a union type, but only for a few specific types. When we want to extract most types, we can use the complement of &lt;code&gt;Extract&lt;/code&gt; type, which is &lt;code&gt;Exclude&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In TypeScript, we can use the &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion"&gt;&lt;code&gt;Exclude&lt;/code&gt;&lt;/a&gt; type to get all types from a union type, except for those that are assignable to another union.&lt;/p&gt;

&lt;p&gt;For example, let's redefine our types derived from &lt;code&gt;DayOfWeek&lt;/code&gt; to use &lt;code&gt;Exclude&lt;/code&gt; instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BusinessDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday"&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Weekend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tuesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wednesday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thursday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Friday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "Saturday" | "Sunday"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These types are exactly the same as the ones we defined before, but we defined them using &lt;code&gt;Exclude&lt;/code&gt; instead of &lt;code&gt;Extract&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to use &lt;code&gt;Extract&lt;/code&gt; or &lt;code&gt;Exclude&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;For the most part, &lt;code&gt;Extract&lt;/code&gt; and &lt;code&gt;Exclude&lt;/code&gt; are interchangeable, they are just complements of each other. So the general rule for when to use them is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;Extract&lt;/code&gt; when you only need to extract &lt;strong&gt;a few types&lt;/strong&gt; from a union type&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Exclude&lt;/code&gt; when you need to extract &lt;strong&gt;most types&lt;/strong&gt; from a union type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these types become even more powerful when we leverage each of their respective strengths. For example, we can redefine our day of the week types to use &lt;code&gt;Extract&lt;/code&gt; and &lt;code&gt;Exclude&lt;/code&gt; in combination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Weekend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sunday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "Saturday" | "Sunday"&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BusinessDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DayOfWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Weekend&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version is both much shorter (so it is easier to read) and it also better conveys the meaning and intention behind the types.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you &lt;em&gt;not&lt;/em&gt; use a union type?
&lt;/h2&gt;

&lt;p&gt;Although union types are an excellent modeling tool, there are legitimate reasons to &lt;em&gt;not&lt;/em&gt; use them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When the types are known at compile-time&lt;/strong&gt;, we can use &lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html"&gt;generics&lt;/a&gt; instead to provide further type safety and flexibility. If the types are known ahead of time, then there is no need to use a union type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When we need to enumerate all possibilities at run-time&lt;/strong&gt; (use an &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html"&gt;&lt;code&gt;enum&lt;/code&gt;&lt;/a&gt; instead for this). For example, if we wanted to iterate over all of the days of the week and construct an array, we would need to use an &lt;code&gt;enum&lt;/code&gt;, because union types are a TypeScript-only feature, so it is compiled away when compiling to JavaScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is the difference between an &lt;code&gt;enum&lt;/code&gt; and a union type?
&lt;/h2&gt;

&lt;p&gt;At first, an &lt;code&gt;enum&lt;/code&gt; and a union appear to be almost the same, so what's the difference? The two main differences between an &lt;code&gt;enum&lt;/code&gt; and unions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A union type exists only at compile-time, an &lt;code&gt;enum&lt;/code&gt; exists at compile-time and run-time.&lt;/li&gt;
&lt;li&gt;A union type is an enumeration of any kind of type, an &lt;code&gt;enum&lt;/code&gt; is an enumeration of only strings or numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of these differences, the one that has the most important practical implications is that unions only exist in TypeScript's type system, while an &lt;code&gt;enum&lt;/code&gt; actually exists as an object in JavaScript. Unions are a convenient way to model many types, but they do not actually affect the program's execution in any way. So, when we compile TypeScript to JavaScript, the union type will disappear from the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Note: `Color` does not exist at run-time, so we&lt;/span&gt;
&lt;span class="c1"&gt;// cannot do something like this:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;//                        ^^^^^ ERROR: 'Color' only refers&lt;/span&gt;
&lt;span class="c1"&gt;// to a type, but is being used as a value here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, an &lt;code&gt;enum&lt;/code&gt; is essentially an alias for a JavaScript object. It is both a type and a value at the same time, similar to how a class can act as both a type and an actual value in JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Green&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Note: `Color` _does_ exist as an actual value at run-time,&lt;/span&gt;
&lt;span class="c1"&gt;// so we can use it just like any object:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; ["Red", "Green", "Blue"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, if it is necessary to be able to iterate over all the possible values and use the values in our program, then an &lt;code&gt;enum&lt;/code&gt; might be a better choice instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Union types are a fantastic feature of TypeScript. They are an ergonomic way to model a finite number of mutually exclusive cases, and allow new cases to be added without breaking any existing code. However, union types do not exist at compile-time, so any programs that need access to the enumerated values should probably use an &lt;code&gt;enum&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;If you're interested in learning more about union types and the theory behind them, check out these additional resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types"&gt;Union types (TypeScript Handbook)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Algebraic_data_type"&gt;Algebraic data types (Wikipedia)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Tagged_union"&gt;Tagged union (Wikipedia)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this post helped you understand union types better, consider sending me a message to me (&lt;a href="https://twitter.com/cammchenry"&gt;@cammchenry&lt;/a&gt;) and let me know what you thought. Happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Do Anything in TypeScript With Type Guards</title>
      <dc:creator>Cameron McHenry</dc:creator>
      <pubDate>Wed, 03 Nov 2021 16:52:19 +0000</pubDate>
      <link>https://dev.to/camchenry/how-to-do-anything-in-typescript-with-type-guards-24h7</link>
      <guid>https://dev.to/camchenry/how-to-do-anything-in-typescript-with-type-guards-24h7</guid>
      <description>&lt;p&gt;This article was originally published on my blog: &lt;a href="https://camchenry.com/blog/typescript-type-guards"&gt;camchenry.com&lt;/a&gt;. If you enjoy this article, please consider joining my mailing list for more content like this one.&lt;/p&gt;




&lt;p&gt;TypeScript is valuable because it enables us to write safe code. Because when every type in the code is known at compile time, we can compile the code with TypeScript and perform type checking, which ensures that the code will not crash or cause errors.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;it is not always possible to know every type at compile time&lt;/strong&gt;, such as when accepting arbitrary data from an external API. To check types at run-time or differentiate between different types, we to need narrow the types using a type guard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is narrowing?
&lt;/h2&gt;

&lt;p&gt;In TypeScript, &lt;a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html"&gt;narrowing&lt;/a&gt; is the process of refining broad types into more narrow types. Narrowing is useful because it allows code to be liberal in the types that it accepts. Then, we can use type guards to narrow the type down to something more useful.&lt;/p&gt;

&lt;p&gt;These are some common examples of narrowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unknown&lt;/code&gt; or &lt;code&gt;any&lt;/code&gt; to &lt;code&gt;string&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;string | object | number&lt;/code&gt; to &lt;code&gt;string&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;number | null | undefined&lt;/code&gt; to &lt;code&gt;number&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;string&lt;/code&gt; to a custom type like &lt;code&gt;NonEmptyString&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a type guard?
&lt;/h2&gt;

&lt;p&gt;A type guard is a kind of conditional check that narrows a type. Type guards allow for run-time type checking by using expressions to see if a value is of a certain type or not.&lt;/p&gt;

&lt;p&gt;So, what does a type guard look like? These are all examples of type guards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;typeof value === 'string'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;'name' in data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;value instanceof MouseEvent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!value&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A type guard is a special kind of expression that changes the type of a variable. We will look at more examples of type guards in practice later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The kinds of type guards (how to check a type)
&lt;/h2&gt;

&lt;p&gt;Most type guards revolve around regular JavaScript operators, which are given extra abilities in TypeScript that make it possible to narrow types by writing typical JavaScript code. So, it is possible that you've used a type guard before without even realizing it!&lt;/p&gt;

&lt;p&gt;Fundamentally, &lt;strong&gt;every type guard relies on checking that some expression evaluates to true or false.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a result, the first kind of type guard which we will look at is a simple truthiness check. But we can utilize more complex type guards like &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;typeof&lt;/code&gt;, and &lt;code&gt;instanceof&lt;/code&gt; that tell us much more information.&lt;/p&gt;

&lt;p&gt;In addition to all of these built-in type guards, we can can go even further and create our own custom type guards that can check &lt;em&gt;any type&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boolean type guard (truthiness)
&lt;/h3&gt;

&lt;p&gt;As stated previously, checking the truthiness of a value is the essence of all type guards.&lt;/p&gt;

&lt;p&gt;However, a boolean type guard only checks the truthiness of a value, but gives us no additional information beyond that. Other more complex type guards can check more complex types or verify more properties, but the boolean type guard is the most basic type guard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getAvailableRooms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`There are &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; hotel rooms available to book.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sorry, all rooms are currently booked.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;getAvailableRooms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Sorry, all rooms are currently booked."&lt;/span&gt;
&lt;span class="nx"&gt;getAvailableRooms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "There are 5 hotel rooms available to book."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using a boolean type guard, the value is implicitly casted to a boolean. This has a logical interpretation most of the time, but not always.&lt;/p&gt;

&lt;p&gt;For example, if use a boolean type guard to check a type of &lt;code&gt;number | undefined&lt;/code&gt;, we might expect that it will only exclude the &lt;code&gt;undefined&lt;/code&gt; case. However, it will also rule out the case where the value is 0, which might not be what you expect in some cases. For more information on this common bug, check out Kent C. Dodd's article, "&lt;a href="https://kentcdodds.com/blog/use-ternaries-rather-than-and-and-in-jsx"&gt;Use ternaries rather than &amp;amp;&amp;amp; in JSX&lt;/a&gt;."&lt;/p&gt;

&lt;h3&gt;
  
  
  Equality type guard
&lt;/h3&gt;

&lt;p&gt;In the boolean type guard, we checked the &lt;em&gt;truthiness&lt;/em&gt; of an expression. &lt;strong&gt;In an equality type guard, we check the &lt;em&gt;value&lt;/em&gt; of an expression.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This kind of type guard is useful when we know all of the possible values of a type. For example, if we have an enumeration of string or number values, or if we want to know that a value is not &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example where we use an equality type guard to &lt;em&gt;remove&lt;/em&gt; &lt;code&gt;undefined&lt;/code&gt; from the type of a variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;morning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;afternoon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Now the type of `timeOfDay` is narrowed to `morning` | `afternoon`,&lt;/span&gt;
  &lt;span class="c1"&gt;// so we can use string methods on it safely.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Good &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}${&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;getGreeting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// "Hello!"&lt;/span&gt;
&lt;span class="nx"&gt;getGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;afternoon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Good Afternoon!"&lt;/span&gt;
&lt;span class="nx"&gt;getGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;morning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Good Morning!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use a &lt;code&gt;switch&lt;/code&gt; block to accomplish exactly the same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;morning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;afternoon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;afternoon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;morning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Good &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}${&lt;/span&gt;&lt;span class="nx"&gt;timeOfDay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a &lt;code&gt;switch&lt;/code&gt; block like this might be preferable if you have a lot of possible values to check and which might share the same code.&lt;/p&gt;

&lt;p&gt;Discriminated unions deserve their own article, but they are essentially a more powerful version of the equality type guard.&lt;/p&gt;

&lt;p&gt;A discriminated union is a type that has multiple possible types, with a field that allows to us to discriminate (or differentiate) between them. In other words, when we check the value of a single field (like &lt;code&gt;type&lt;/code&gt;), it automatically includes a number of other properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;typeof&lt;/code&gt; type guard
&lt;/h3&gt;

&lt;p&gt;In contrast to the previous example, where we checked the &lt;em&gt;value&lt;/em&gt; of a variable (or expression), with a &lt;code&gt;typeof&lt;/code&gt; type guard, we check the &lt;em&gt;type&lt;/em&gt; of a variable.&lt;/p&gt;

&lt;p&gt;When there is a value which has several possible types, like &lt;code&gt;string | number&lt;/code&gt;, we can use &lt;code&gt;typeof&lt;/code&gt; to figure out which type it is.&lt;/p&gt;

&lt;p&gt;For example, we can use &lt;code&gt;typeof&lt;/code&gt; to write a comparison function that compares two values to each other and returns the difference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Both a and b are numbers, so we can compare them directly.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We can use string methods on `a` and `b` safely.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`Cannot compare unrelated types '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' and '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; -1&lt;/span&gt;
&lt;span class="nx"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 1&lt;/span&gt;
&lt;span class="nx"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;321&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; -198&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The biggest limitation of the &lt;code&gt;typeof&lt;/code&gt; guard is that it can only differentiate between &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof"&gt;types that JavaScript recognizes&lt;/a&gt;. The types that &lt;code&gt;typeof&lt;/code&gt; can check are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;number&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bigint&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;object&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;symbol&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;function&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;instanceof&lt;/code&gt; type guard
&lt;/h3&gt;

&lt;p&gt;When we have a variable that is an instance of a class, we can use &lt;code&gt;instanceof&lt;/code&gt; to check whether if the variable has that type or not.&lt;/p&gt;

&lt;p&gt;For example, the DOM APIs define many classes and subclasses which can be quickly checked using &lt;code&gt;instanceof&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;MouseEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// `event` now has type `MouseEvent`, so we can access mouse-specific properties&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`A mouse event occurred at (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// `event` now has type `KeyboardEvent`, so we can access key-specific properties&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`A keyboard event occurred: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An event occurred: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful when dealing with potentially generic DOM objects, because a single &lt;code&gt;instanceof&lt;/code&gt; check grants access to all of the properties and methods of the class.&lt;/p&gt;

&lt;p&gt;This can also be used to differentiate between common objects in JavaScript, like &lt;code&gt;Map&lt;/code&gt;, &lt;code&gt;Date&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, or &lt;code&gt;Set&lt;/code&gt;. For example, we can create a function to create a lookup table which accepts many possible inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Creates a Map which returns some value given a string key&lt;/span&gt;
&lt;span class="c1"&gt;// (ignoring the fact that the Map constructor already accepts some of these)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createLookupTable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// `db` has type `[string, Value][] | Map&amp;lt;string, Value&amp;gt; | Record&amp;lt;string, Value&amp;gt;`&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// `db` now has type `[string, Value][]`&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// `db` has type `Map&amp;lt;string, Value&amp;gt; | Record&amp;lt;string, Value&amp;gt;`&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// `db` now has type `Map&amp;lt;string, Value&amp;gt;`&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// `db` has type `Record&amp;lt;string, Value&amp;gt;`&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;createLookupTable&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;14.99&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shirt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;24.95&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Map (2) {"hat" =&amp;gt; 14.99, "shirt" =&amp;gt; 24.95}&lt;/span&gt;

&lt;span class="nx"&gt;createLookupTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;14.99&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shirt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;24.95&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Map (2) {"hat" =&amp;gt; 14.99, "shirt" =&amp;gt; 24.95}&lt;/span&gt;

&lt;span class="nx"&gt;createLookupTable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;14.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;shirt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;24.95&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Map (2) {"hat" =&amp;gt; 14.99, "shirt" =&amp;gt; 24.95}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is another example using &lt;code&gt;instanceof&lt;/code&gt; to check if a type is a &lt;code&gt;Date&lt;/code&gt; or a &lt;code&gt;string&lt;/code&gt; and decide whether to construct a new &lt;code&gt;Date&lt;/code&gt; object or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2021-05-06 03:25:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Date: "2021-05-06T07:25:00.000Z"&lt;/span&gt;
&lt;span class="nx"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2021-05-06 03:25:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; Date: "2021-05-06T07:25:00.000Z"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;in&lt;/code&gt; type guard
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;in&lt;/code&gt; type guard allows us to differentiate between multiple types by checking if an object has a specific property. In JavaScript, the &lt;code&gt;in&lt;/code&gt; operator, like all type guards, returns a boolean value that indicates if the object has the property or not. For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, we can use &lt;code&gt;in&lt;/code&gt; to differentiate objects that have different sets of properties. For example, we can use it to differentiate between different types of classes (in this case, events):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MouseEvent&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// event now has type `KeyboardEvent`&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`A keyboard event occurred: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// event now has type `MouseEvent`&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`A mouse event occurred: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing here is that &lt;code&gt;key&lt;/code&gt; is only defined for &lt;code&gt;KeyboardEvent&lt;/code&gt;, but not for &lt;code&gt;MouseEvent&lt;/code&gt;. If the property we check exists in multiple cases, the narrowing will not work. For example, the following code will not work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;EventInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mouse&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleEventInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This type guard will NOT work:&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// event still has type `EventInput`, so the type guard does not&lt;/span&gt;
    &lt;span class="c1"&gt;// do any narrowing in this case&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though not always related to its use for narrowing types, the &lt;code&gt;in&lt;/code&gt; operator is also often used to check for browser support of certain features.&lt;/p&gt;

&lt;p&gt;For example, the guard &lt;code&gt;'serviceWorker' in navigator&lt;/code&gt; checks whether the browser supports service workers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assertion type guard (or assertion function)
&lt;/h3&gt;

&lt;p&gt;In TypeScript 3.7, TypeScript added support for &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions"&gt;assertion functions&lt;/a&gt;. An assertion function is a function that assumes a condition is always true, and throws an error when it does not.&lt;/p&gt;

&lt;p&gt;To create an assertion function, we need to add something called an "assertion signature," which is a formal declaration of what the function will assert. The assertion signature is additional information about a function (like a return type) that lets the TypeScript compiler narrow the type.&lt;/p&gt;

&lt;p&gt;Let's look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;assertString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;asserts&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Expected 'string', got: '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;assertString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// x now has type 'string', so it is safe to use string methods&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previously, we discussed how all type guards are based around a boolean check. That is still true in this case, but the actual usage is slightly different from other type guards.&lt;/p&gt;

&lt;p&gt;With other type guards, we typically used something like &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;switch&lt;/code&gt; to create different branches of execution. With an assertion function, the two branches are: continue as normal, or stop the script (throw an error).&lt;/p&gt;

&lt;p&gt;Other than the difference of how an assertion type guard can throw an exception, assertion type guards are similar to other type guards. However, something that we must be careful about is accidentally creating a type guard which asserts the &lt;strong&gt;wrong&lt;/strong&gt; condition.&lt;/p&gt;

&lt;p&gt;This is one way that we can end up with a &lt;strong&gt;false sense of safety&lt;/strong&gt;. Here is an example where the function asserts something, but the actual code asserts nothing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;assertString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;asserts&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This check does not match the assertion signature&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;assertString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// We get a run-time exception here (!!!), which TypeScript should&lt;/span&gt;
&lt;span class="c1"&gt;// be able to prevent under normal circumstances:&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// "TypeError: x.toLowerCase is not a function"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  User-defined (custom) type guard
&lt;/h3&gt;

&lt;p&gt;Most type guards have limitations to what they can check, such as only primitive types for &lt;code&gt;typeof&lt;/code&gt;, or only classes for &lt;code&gt;instanceof&lt;/code&gt;. But with user-defined type guards, there are no limitations on what we can check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom type guards are the most powerful kind of type guard&lt;/strong&gt;, because we can verify any type, including ones that we defined ourselves, as well as built-in types from JavaScript or the DOM. The main downside of custom type guards is that they are not predefined, so we have to write them ourselves.&lt;/p&gt;

&lt;p&gt;There are a few built-in custom type guards though, such as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray"&gt;&lt;code&gt;Array.isArray&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// data now has type "array", so it is safe to use array methods&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next section, we will look at all of the different ways that we can define our own type guard functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type guard functions
&lt;/h2&gt;

&lt;p&gt;A type guard function is a function that returns a value and has a &lt;em&gt;type predicate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A type predicate is an additional declaration that is added to a function (like a return type) which gives additional information to TypeScript and allows it to narrow the type of a variable. For example, in the definition of &lt;code&gt;Array.isArray&lt;/code&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the type predicate is &lt;code&gt;arg is any[]&lt;/code&gt;. In spoken word, the signature of this function might be: "&lt;code&gt;isArray&lt;/code&gt; takes one argument of type &lt;code&gt;any&lt;/code&gt; and checks if it is an array." In general, type predicates take the form: &lt;code&gt;variable is type&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a function to be eligible as a type guard, it must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return a boolean value&lt;/li&gt;
&lt;li&gt;Have a type predicate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The type predicate replaces the return type, because a function with a type predicate must always return a boolean value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of type guard functions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Check if a value is a string
&lt;/h4&gt;

&lt;p&gt;This example is essentially a reusable form of the built-in &lt;code&gt;typeof&lt;/code&gt; type guard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Check if a value is defined (not null or undefined)
&lt;/h4&gt;

&lt;p&gt;A common use case for type guards is to refine the type of something like &lt;code&gt;Type | null&lt;/code&gt; or &lt;code&gt;Type | undefined&lt;/code&gt; down to just &lt;code&gt;Type&lt;/code&gt;, effectively eliminating the null or undefined case. We can do this by accepting a generic type which can be null or undefined, and adding a type predicate to remove &lt;code&gt;null | undefined&lt;/code&gt; from the type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isDefined&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, it can be used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDefined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// x is defined, so it is safe to use methods on x&lt;/span&gt;
  &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Remove all values &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; values from array
&lt;/h4&gt;

&lt;p&gt;Using the &lt;code&gt;isDefined&lt;/code&gt; type guard we just defined, we can use it with the built-in &lt;code&gt;Array.filter&lt;/code&gt; function, which has special support for type predicates. The &lt;code&gt;Array.filter&lt;/code&gt; function is defined like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Filtered&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Filtered&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Filtered&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The definition here has been altered slightly for improved understanding and readability). Essentially, every usage of &lt;code&gt;Array.filter&lt;/code&gt; is a type guard, except in most cases the type before and after calling &lt;code&gt;Array.filter&lt;/code&gt; is the same type.&lt;/p&gt;

&lt;p&gt;But if the function passed to &lt;code&gt;Array.filter&lt;/code&gt; &lt;em&gt;narrows&lt;/em&gt; the type (like a type guard), then the return type of &lt;code&gt;Array.filter&lt;/code&gt; changes. So we can use our &lt;code&gt;isDefined&lt;/code&gt; type guard to remove all &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; values from the array, as well as removing &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; types from the array items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 'values' is an array of strings, but can have null or undefined values&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// We can safely assign 'filtered' to an array of strings (string[])&lt;/span&gt;
&lt;span class="c1"&gt;// because `isDefined` changes the type of the variable 'values'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Check if a number is positive
&lt;/h4&gt;

&lt;p&gt;A common use-case for creating our own types is so that we can ensure certain conditions are met. For example, we might want to ensure that an object has certain properties, a string is not empty, or a number is positive.&lt;/p&gt;

&lt;p&gt;First, we need to create a custom &lt;code&gt;PositiveNumber&lt;/code&gt; type, and a type guard to check for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PositiveNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isPositive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a new type of number, we use a technique called "type branding." Essentially, we add a phantom property to the number type to differentiate it from all other types of numbers. In this case, I chose to use &lt;code&gt;{ __type: 'PositiveNumber' }&lt;/code&gt;, but we could picked any arbitrary key/value, as long as it is unique and not already defined.&lt;/p&gt;

&lt;p&gt;The important thing is that we cannot create &lt;code&gt;PositiveNumber&lt;/code&gt; by declaring a variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ERROR: Type 'number' is not assignable to type 'PositiveNumber&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may seem inconvenient, but it is exactly why it allows us to write safe code, because we must always check conditions with the type guard and prevents us from writing code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an example of how we might use this type guard, we can write a square root function which accepts only positive numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;squareRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PositiveNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we can use the type guard to compute the square root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;squareRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ERROR: ^^^ 'number' is not assignable to parameter of type 'PositiveNumber'&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPositive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// OK: Now x has type 'PositiveNumber', so we can take the square root&lt;/span&gt;
  &lt;span class="nx"&gt;squareRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Check if a string is a GUID
&lt;/h4&gt;

&lt;p&gt;Similar to the previous example, we can create a custom &lt;code&gt;Guid&lt;/code&gt; type that is based on the &lt;code&gt;string&lt;/code&gt; type and write a type guard to check for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Guid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Guid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;guidPattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9a-f&lt;/span&gt;&lt;span class="se"&gt;]{8}&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9a-f&lt;/span&gt;&lt;span class="se"&gt;]{4}&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-5&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;0-9a-f&lt;/span&gt;&lt;span class="se"&gt;]{3}&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;089ab&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;0-9a-f&lt;/span&gt;&lt;span class="se"&gt;]{3}&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9a-f&lt;/span&gt;&lt;span class="se"&gt;]{12}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isGuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Guid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;guidPattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an example of how to use this type and type guard in practice, we will create a list of users that can be searched by GUID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ERROR:   ^^ Argument of type 'string' is not assignable to parameter of type 'Guid'&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isGuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// OK: id now has type `Guid`:&lt;/span&gt;
  &lt;span class="nx"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Check if a value is a valid React element (&lt;code&gt;React.isValidElement&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://reactjs.org/docs/react-api.html#isvalidelement"&gt;&lt;code&gt;isValidElement&lt;/code&gt;&lt;/a&gt; function included with React checks if a value is a valid React element, which can be rendered by React.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isValidElement&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation of this function is not relevant here, but it is a perfect example of a common type guard function that verifies a custom type that cannot be verified with other type guards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and cons of custom type guard functions
&lt;/h3&gt;

&lt;p&gt;Custom type guard functions are powerful and sometimes be the only option in order to write type-safe code. However, they can be a tricky to write and are susceptible to mistakes.&lt;/p&gt;

&lt;p&gt;The advantages of custom type guard functions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: can check any type, including custom types that we define&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run-time type checking&lt;/strong&gt;: allows type-checking at run-time, ensuring that safety is ensured both when code is compiled, and also when it is running&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable&lt;/strong&gt;: type guard functions allow us to combine multiple type guards into one and easily use them in multiple places&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The disadvantages of a custom type guard function are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual&lt;/strong&gt;: type guard functions have to be written manually (currently no automatic way to generate type guards)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: using type guard functions has a slight overhead to call the function and run the checks (negligible in practice)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragile&lt;/strong&gt;: custom type guards can be implemented incorrectly on accident, which may provide a false sense of security and safety&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where can a type guard be used?
&lt;/h2&gt;

&lt;p&gt;Now that we know all about the available type guards, we will briefly look at where we can use type guards. There are a limited number of places that type guards can be used. The most common place they are used is in a &lt;code&gt;if/else&lt;/code&gt; block, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// value has type 'string' in this block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// value does NOT have type 'string' in this block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we can use type guards in an &lt;code&gt;if/else&lt;/code&gt; block, then you might expect that we can also use them with the ternary operator, since it's a shorthand for an &lt;code&gt;if/else&lt;/code&gt; block. And you would be correct!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="cm"&gt;/* value has type 'string' in this block */&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="cm"&gt;/* value does NOT have type 'string' in this block */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition, since &lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-4-4/#cfa-aliased-conditions"&gt;TypeScript 4.4&lt;/a&gt;, we can use type guards with aliased conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// value has type 'string' in this block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// value does NOT have type 'string' in this block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond just &lt;code&gt;if/else&lt;/code&gt;, type guards can also be used in a &lt;code&gt;while&lt;/code&gt; block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// value has type 'string' in this block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, type guards are also compatible with a &lt;code&gt;switch/case&lt;/code&gt; block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;// value has type 'string' in this block&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Type guards are conditional checks that allow types to be refined from one type to another, allowing us to write code that is type-safe and easy to write at the same time. Since TypeScript is a superset of JavaScript, many common operators like &lt;code&gt;typeof&lt;/code&gt; or &lt;code&gt;instanceof&lt;/code&gt; act as type guards. But, we can also use custom type guards to verify &lt;em&gt;any&lt;/em&gt; condition and &lt;em&gt;any&lt;/em&gt; type, given enough effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In general, I would recommend using the type guard that feels the most natural, which will come from experience. Don't write a custom type guard function when a simple &lt;code&gt;typeof&lt;/code&gt; check can suffice. However, it may be necessary to write a custom type guard.&lt;/p&gt;

&lt;p&gt;To summarize the strengths of each type guard, here is a summary table.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type guard&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Boolean / truthiness&lt;/td&gt;
&lt;td&gt;Rule out falsy values like &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;''&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Equality&lt;/td&gt;
&lt;td&gt;Narrow multiple possible types down to a single type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;typeof&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Narrow a type to a primitive type (like &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;number&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;instanceof&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check if a value is an instance of a specific class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;in&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check if a property can be accessed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assertion function&lt;/td&gt;
&lt;td&gt;Assert invariants that should always be true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom type guard function&lt;/td&gt;
&lt;td&gt;Check that a type meets some arbitrary conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If this article was helpful, let me know on Twitter at &lt;a href="https://twitter.com/cammchenry"&gt;@cammchenry&lt;/a&gt;! If you enjoy guides like this, consider signing up for my mailing list to be notified when new posts are published.&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Delete Dead Code in TypeScript Projects</title>
      <dc:creator>Cameron McHenry</dc:creator>
      <pubDate>Tue, 19 Oct 2021 19:09:25 +0000</pubDate>
      <link>https://dev.to/camchenry/how-to-delete-dead-code-in-typescript-projects-1i89</link>
      <guid>https://dev.to/camchenry/how-to-delete-dead-code-in-typescript-projects-1i89</guid>
      <description>&lt;p&gt;This was originally posted on my blog: &lt;a href="https://camchenry.com/blog/deleting-dead-code-in-typescript"&gt;https://camchenry.com/blog/deleting-dead-code-in-typescript&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is dead code?
&lt;/h2&gt;

&lt;p&gt;"Dead code" is code that is never used. It is not referenced by any other code, it is not imported, it is not used in the final build in any way.&lt;/p&gt;

&lt;p&gt;Refactoring a project to make certain types, methods, or properties obsolete without removing that obsolete code will create dead code. Changing the direction of a project, like choosing to use a different API or library can also produce dead code. On large projects with many different teams and shifting priorities, &lt;strong&gt;the occurrence of dead code is inevitable&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should you delete dead code?
&lt;/h2&gt;

&lt;p&gt;There are many reasons why you should delete dead code. There are many effects that dead code can have on a large project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dead code must be compiled, which slows down the compilation time. It may be included in the final output too, increasing the total executable size.&lt;/li&gt;
&lt;li&gt;Dead code must be downloaded, which increase the project size.&lt;/li&gt;
&lt;li&gt;Dead code may reference other dead code and make it appear important.&lt;/li&gt;
&lt;li&gt;Dead code must be understood, which makes the project harder to maintain and work on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you delete dead code, you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make it easier to understand and maintain a project.&lt;/li&gt;
&lt;li&gt;Speed up compilation time.&lt;/li&gt;
&lt;li&gt;Decrease the project size.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a result of removing dead code, a program will be faster to download and compile, and its output executable will be smaller and faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to find dead code
&lt;/h2&gt;

&lt;p&gt;First, you will need to be using TypeScript in your projects for these tools to work. TypeScript simplifies the difficult task of determining whether any given piece of code is actually used or not.&lt;/p&gt;

&lt;p&gt;Second, you will want to install &lt;a href="https://github.com/nadeesha/ts-prune"&gt;&lt;code&gt;ts-prune&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/pzavolinsky/ts-unused-exports"&gt;&lt;code&gt;ts-unused-exports&lt;/code&gt;&lt;/a&gt; globally, so they can be used for any project. Run these commands in a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ts-prune ts-unused-exports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my experience, no single tool will give perfect results for identifying dead code. So, I recommend alternating between both of these tools to find dead code.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use &lt;code&gt;ts-prune&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To run &lt;code&gt;ts-prune&lt;/code&gt;, run the following command in a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ts-prune &lt;span class="nt"&gt;--project&lt;/span&gt; tsconfig.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see some output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\src\components\Avatar\index.ts:18 - STYLE_CLASSES
\src\components\BulkActions\index.ts:26 - BulkAction
\src\components\CheckableButton\index.ts:13 - CheckableButtonProps
\src\components\Choice\index.ts:9 - ChoiceProps
\src\components\Combobox\index.ts:2 - ComboboxTextField
\src\components\DataTable\utilities.ts:34 - isEdgeVisible (used in module)
\src\components\DropZone\index.ts:38 - DropZoneFileType
\src\components\IndexTable\index.ts:6 - CellProps
\src\components\IndexTable\index.ts:11 - Cell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The left-hand side is the file and line number of where the potential dead code occurs. The right-hand side is the name of the export that appears to be unused. If the export is only used internally, it will have the text &lt;code&gt;(used in module)&lt;/code&gt; appended to it. If the default export is unused, the right-hand side will say &lt;code&gt;default&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I'm OK with unused exports as long as the export is used internally, so I recommend filtering out the lines with &lt;code&gt;(used in module)&lt;/code&gt; in them. You can do that by piping the output into &lt;code&gt;grep&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ts-prune &lt;span class="nt"&gt;--project&lt;/span&gt; tsconfig.json | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s1"&gt;'(used in module)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to use &lt;code&gt;ts-unused-exports&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To run &lt;code&gt;ts-unused-exports&lt;/code&gt;, run these commands in a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ts-unused-exports tsconfig.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which should create some output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src\utilities\features\index.ts: Features, useFeatures
src\utilities\focus-manager\index.ts: FocusManagerContextType
src\utilities\frame\index.ts: FrameContextType
src\utilities\index-table\index.ts: useRowHovered
src\utilities\listbox\index.ts: ListboxContextType
src\utilities\media-query\index.ts: MediaQueryContextType
src\utilities\portals\index.ts: PortalsManager
src\utilities\resource-list\index.ts: ResourceListContextType
src\utilities\theme\index.ts: ProcessedThemeConfig
src\utilities\theme\types.ts: ThemeLogo, Role, AppThemeConfig
src\utilities\theme\utils.ts: buildCustomPropertiesNoMemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The left-hand side lists the file that contains unused exports. The right-hand side lists the names of unused exports in the file. If the default module export is unused, the right-hand side will include &lt;code&gt;default&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will often ignore unused types, since it is typically not much of an issue. In many cases, it is indicative of work that&lt;br&gt;
is in progress. It is also not included in the compiled JavaScript (since types don't exist in JavaScript), so leaving it in the project won't affect the build size. To do that, add the &lt;code&gt;--allowUnusedTypes&lt;/code&gt; flag to the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ts-unused-exports tsconfig.json &lt;span class="nt"&gt;--allowUnusedTypes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to delete dead code
&lt;/h2&gt;

&lt;p&gt;Unfortunately, you will have to manually go through each result and determine whether to keep it or delete it. There is often a moderate false positive rate when it comes to finding dead code. &lt;strong&gt;Not all unused code is dead code, but all dead code is unused code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If any patterns emerge while identifying dead code, I recommend automating the process. Create scripts to combine the results from these tools. Filter it to remove any false positives. Then, automatically generate diffs to remove dead code. For small projects, this is probably overkill (and that's OK). For large projects, this is a &lt;a href="https://en.wikipedia.org/wiki/Force_multiplication"&gt;force multiplier&lt;/a&gt; that will make everyone on your team more productive.&lt;/p&gt;

&lt;p&gt;When deleting dead code, there are a couple exceptions that I always keep in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Exported component prop types are OK. These may not be "used," but they will likely be used by consumers of the module to create derivative types.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// OK:&lt;/span&gt;
   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ComponentProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Exported default values are OK. These allow consumers of a module to access the implicit default values of objects and functions, which are otherwise inaccessible programmatically.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// OK:&lt;/span&gt;
   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultFadeTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fadeTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaultFadeTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Recently added code (less than a month old) is probably OK. Sometimes in-progress work will appear unused because it is incomplete.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// Probably OK:&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="cm"&gt;/* TODO: Going to implement this next week */&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="c1"&gt;// NOT OK:&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="cm"&gt;/* TODO: Going to implement this next week ... 2015-06-01 (6 years ago) */&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Metadata and specific code may be OK. If there are pieces of code that serve a special purpose (e.g. preprocessed by another tool, expected by a framework, etc.) then it may not be unused or dead code. For example, server-side rendered frameworks may export functions that are not used in the client output, but are rendered on the server instead.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// OK: special function used by the Next.js framework&lt;/span&gt;
   &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Deleting dead code is a worthwhile effort that can make working in a project faster and easier. Using the &lt;code&gt;ts-prune&lt;/code&gt; and &lt;code&gt;ts-unused-export&lt;/code&gt; tools, we can simplify the process of identifying dead code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are a junior developer&lt;/strong&gt;, automating the process of finding dead code and deleting it is a great senior-level task to learn how to do. Everyone on your team will appreciate having less code to download, compile, and understand. And it will help you understand your codebase better. You'll probably learn many other useful skills along the way too.&lt;/p&gt;

&lt;p&gt;Good luck and happy hunting!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Power Up the React Context API with TypeScript</title>
      <dc:creator>Cameron McHenry</dc:creator>
      <pubDate>Fri, 08 Oct 2021 16:05:06 +0000</pubDate>
      <link>https://dev.to/camchenry/how-to-power-up-the-react-context-api-with-typescript-5hei</link>
      <guid>https://dev.to/camchenry/how-to-power-up-the-react-context-api-with-typescript-5hei</guid>
      <description>&lt;p&gt;This post was originally published on my blog, &lt;a href="https://camchenry.com/blog/react-typescript-context"&gt;camchenry.com&lt;/a&gt;. If you find this post interesting, check out my website for more content like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the React Context API?
&lt;/h2&gt;

&lt;p&gt;React Context is one of the core React APIs that can be used anytime you are developing with React. Context allows us to create a piece of state that is globally shared among many different components.&lt;br&gt;
For example, an application might have a context for the current locale, language, or theme, because that data will be used by&lt;br&gt;
many different components. Context is ideal for globally shared values.&lt;/p&gt;


(NOTE: In this article the terms "Context" (uppercase) and "context" (lowercase) will be used interchangeably. Generally speaking, these
refer to the same thing. However, "Context" more often refers to the React Context feature, while "context" refers to the
general concept, or a specific instance of context (for example, an "authentication context" may use Context).)

&lt;h3&gt;
  
  
  What problems does React Context solve?
&lt;/h3&gt;

&lt;p&gt;At its core, Context helps to solve one main issue: "prop drilling." Prop drilling is the name for when a property&lt;br&gt;
must be passed down through an entire component tree in order to render the application.&lt;/p&gt;

&lt;p&gt;For example, suppose that we store information about a user's application preferences (language, timezone, privacy, etc.) and need to use that to render the application correctly. To render the application, we must write something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="na"&gt;preferences&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;preferences&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// Inside App:&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Profile&lt;/span&gt; &lt;span class="na"&gt;preferences&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;preferences&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// Inside Profile:&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Settings&lt;/span&gt; &lt;span class="na"&gt;preferences&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;preferences&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ... and so on&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ultimately, we end up writing the same code repeatedly in order to pass that state down. Now, if we ever have to rename &lt;code&gt;preferences&lt;/code&gt; or change its type, we have to change it for every component that passes that state down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's a huge pain&lt;/strong&gt;, especially for large applications, where it's not unheard of to have components that are nested dozens of layers deep inside of other components.&lt;/p&gt;

&lt;p&gt;In addition to the increased effort, this sort of behavior also makes components less flexible, because they are expected to take certain properties, and be nested in certain ways. So, restructuring and moving components around becomes more difficult.&lt;/p&gt;

&lt;p&gt;So, how can we solve the prop drilling problem?&lt;/p&gt;

&lt;p&gt;Enter React Context.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Context solves the problems with prop drilling
&lt;/h3&gt;

&lt;p&gt;Context solves the problems that come from prop drilling by allowing components to "skip" an arbitrary number of layers in the component tree. In this way, components can access directly shared state directly.&lt;/p&gt;

&lt;p&gt;In a context, there are two main pieces: the &lt;strong&gt;provider&lt;/strong&gt; and the &lt;strong&gt;consumer&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The provider is the component where the shared state is defined. All components under a provider will be rerendered when the state changes.&lt;/li&gt;
&lt;li&gt;A consumer is the component where the state from the provider is accessed and used. As long as it is a descendent of the provider, it can access the provider's state. &lt;strong&gt;A consumer always reads the value of the nearest provider.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  An Analogy for Context
&lt;/h4&gt;

&lt;p&gt;Imagine that a context is like a wireless network, where the provider is a 🌐 wireless network, and the consumer is a device like a 💻 laptop.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  Summary of comparison between wireless network and context
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;🌐 Wireless Network&lt;/th&gt;
      &lt;th&gt;💡 Context&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;When a laptop is connected to the network, can send and receive data from anywhere, regardless of physical location&lt;/td&gt;
      &lt;td&gt;When a consumer is nested under a provider, the consumer can send and receive state from anywhere, regardless of how it is nested (or how deeply nested).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;A laptop will try to find the closest access point in the network to get the best wireless signal.&lt;/td&gt;
      &lt;td&gt;A consumer will try to find the closest provider (nearest ancestor) to get the current state.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;If there is no wireless access point, devices will not work.&lt;/td&gt;
      &lt;td&gt;If there is no context provider, then consumers will only get the default value.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A laptop that is connected to the network is like a consumer component that is nested under the provider. As long as the&lt;br&gt;
laptop is connected, it can communicate and receive data regardless of where it is physically located. In the same way, as long as a consumer is under the provider, it can exist anywhere in the component tree and access state directly.&lt;/p&gt;

&lt;p&gt;Similarly, a laptop always tries to find the closest access point in order to get the best signal possible. This is like the behavior of the consumer, which always reads the value of the nearest (least nested) provider. If there's no network (i.e., there is no context provider), then our laptop (consumer) can't work!&lt;/p&gt;
&lt;h3&gt;
  
  
  How do we define a context?
&lt;/h3&gt;

&lt;p&gt;Now that we understand what a context is and the problems that it solves, how do we actually create a context? The React API&lt;br&gt;
offers two functions to create and use contexts, which are aptly named &lt;code&gt;createContext&lt;/code&gt; and &lt;code&gt;useContext&lt;/code&gt;, respectively.&lt;/p&gt;

&lt;p&gt;For a simple example, we will create a theme context which tells all consumers whether the current theme is 🌚 &lt;code&gt;dark&lt;/code&gt; or 🌞 &lt;code&gt;light&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a context called &lt;code&gt;ThemeContext&lt;/code&gt;, which has a default value of &lt;code&gt;light&lt;/code&gt;. The first argument of &lt;code&gt;createContext&lt;/code&gt; is a default value which will be used if there are no providers. We will cover how to create a context without a default value later.&lt;/p&gt;

&lt;p&gt;(NOTE: The &lt;code&gt;ThemeContext&lt;/code&gt; variable is uppercase because &lt;code&gt;createContext&lt;/code&gt; returns an object which contains components.&lt;br&gt;
The JSX convention is that components always start with an uppercase letter. So, that means we should uppercase &lt;code&gt;ThemeContext&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Then, in our application we would render the context just like any other component. In this case, we &lt;strong&gt;don't render &lt;code&gt;ThemeContext&lt;/code&gt; directly&lt;/strong&gt; (because it is an object), but instead we render &lt;code&gt;ThemeContext.Provider&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"light"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... rest of the application code here ... */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, our consumer is a component that calls &lt;code&gt;useContext&lt;/code&gt; to access the state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrentThemeDisplay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// this will be "light"&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can place &lt;code&gt;CurrentThemeDisplay&lt;/code&gt; anywhere underneath the &lt;code&gt;ThemeContext.Provider&lt;/code&gt; and it will always get the current theme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"light"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrentThemeDisplay&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ultimately, this example will end up rendering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;light&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A note about class-based Context
&lt;/h3&gt;

&lt;p&gt;There is a class-based version of React Context that uses "render props" and the &lt;code&gt;ThemeContext.Consumer&lt;/code&gt; component. However, if you are just starting a new React application, I would recommend that you do not use these APIs.&lt;br&gt;
While working on a large React application, I've never had any need to use the old class API or render props.&lt;/p&gt;

&lt;p&gt;React Hooks completely revolutionized the way that we can interact with a context and makes it much easier to reuse contexts&lt;br&gt;
and compose them together. In my opinion, the newer, functional API is easier to understand and scales very well to large applications.&lt;/p&gt;



&lt;h2&gt;
  
  
  How TypeScript helps us work with contexts
&lt;/h2&gt;

&lt;p&gt;So far, we've covered the basics of how to use the Context API, but how does TypeScript help us use context more effectively?&lt;/p&gt;

&lt;p&gt;To answer that, let's look at some of the issues that we might experience when using JavaScript and contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing a non-existent property in the context could cause an error&lt;/li&gt;
&lt;li&gt;Renaming a property in the context, or change its type (e.g., from &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;object&lt;/code&gt;) means we have to check every instance where that context is used&lt;/li&gt;
&lt;li&gt;May be possible to put context into invalid states (misspelled string literals, wrong types, etc.)&lt;/li&gt;
&lt;li&gt;Have to reference where the context is defined originally to figure out what properties it contains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most or all of these issues are typical with any JavaScript application, not just ones that use Context. However, TypeScript can solve or mitigate all of these issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing a non-existent property in a context will cause a &lt;strong&gt;compile error&lt;/strong&gt;, preventing any misuse of the context&lt;/li&gt;
&lt;li&gt;Renaming a property or changing the type of a property in the context will cause a &lt;strong&gt;compile error&lt;/strong&gt;, if any code relied on the old name or type&lt;/li&gt;
&lt;li&gt;All types are checked, so invalid context states will &lt;strong&gt;not compile&lt;/strong&gt;, preventing many classes of bugs&lt;/li&gt;
&lt;li&gt;A typed context enables IDEs (like Visual Studio Code) to autocomplete what properties are available in a context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Furthermore, we don't incur any run-time cost for these benefits. That is, using TypeScript doesn't make our bundle size any larger because all of the types will be removed when compiled.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to use the React Context API with TypeScript
&lt;/h2&gt;

&lt;p&gt;Let's revisit how we defined the theme context example earlier. Now we are going to add explicit types for the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThemeState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we try to provide an invalid value to the context, the application will not compile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ This will NOT compile:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// ERROR: Type '"tomato"' is not assignable to type 'ThemeState'&lt;/span&gt;
  &lt;span class="c1"&gt;//                     ⬇️&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tomato"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrentThemeDisplay&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition, we are also prevented from misusing the value provided from the context. Here is a modified example of the &lt;code&gt;CurrentThemeDisplay&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ This will NOT compile:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrentThemeDisplay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;peach&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ~~~~~~~~~~~~~~~~&lt;/span&gt;
    &lt;span class="c1"&gt;// ERROR: This condition will always return 'false' since the&lt;/span&gt;
    &lt;span class="c1"&gt;// types 'ThemeState' and '"peach"' have no overlap.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🍑 Peach&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to provide default values to a React Context
&lt;/h3&gt;

&lt;p&gt;As mentioned earlier, the &lt;code&gt;createContext&lt;/code&gt; function requires that we pass a default value as the first argument. So, if we want to provide a default default, then we can just say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if we don't want to provide a default value though? This may come up if we want to &lt;strong&gt;require&lt;/strong&gt; that a provider is defined somewhere in our application. For example, maybe we want to fetch information from an API and use that as a default value.&lt;/p&gt;

&lt;p&gt;To do this, we still have to provide a default value to &lt;code&gt;createContext&lt;/code&gt;, but we can throw an error if there was no value in the context (which means that no provider was rendered).&lt;/p&gt;

&lt;h4&gt;
  
  
  Theme context example with "no default value"
&lt;/h4&gt;

&lt;p&gt;As an example, let's create a new version of the theme context which tells the application about the current theme. In this case, it's perhaps a bit contrived for a theme provider why you might want to have "no default value," but there are good reasons to do so for something like an authentication context or other context that might make API calls.&lt;/p&gt;

&lt;p&gt;To keep things simple though, we will build from our previous theme example.&lt;/p&gt;

&lt;p&gt;We will use &lt;code&gt;null&lt;/code&gt; as a sentinel value that indicates that no provider provided a value and consumers should consider this default value as invalid. So, if the &lt;code&gt;value&lt;/code&gt; is null, we will throw an error. This will then allow TypeScript to infer that the value from the context is definitely defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThemeState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeState&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The context value can either be our expected set of values for the context, or &lt;code&gt;null&lt;/code&gt; (if no provider is created). Then, where we consume the context, we can check if the value is &lt;code&gt;null&lt;/code&gt;, and throw an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrentThemeDisplay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// this will be "light"&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Theme state not found. Try wrapping a parent component with &amp;lt;ThemeContext.Provider&amp;gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we ensure that anywhere we use the theme context, that a theme provider must be rendered before the application works. In this way, we surface potential usage issues with our context much sooner than if we didn't throw an error.&lt;/p&gt;

&lt;p&gt;We also retain the type safety of TypeScript, because throwing an error when &lt;code&gt;theme === null&lt;/code&gt; gives the compiler enough information to narrow the type of &lt;code&gt;ThemeState | null&lt;/code&gt; to just &lt;code&gt;ThemeState&lt;/code&gt;, which makes it safe to render &lt;code&gt;theme&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(NOTE: The error message also includes what went wrong, explains how to fix the error: wrap a parent component with &lt;code&gt;ThemeContext.Provider&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Providing descriptive error messages that indicate clearly went wrong, and some possible ways to fix the issue is immensely valuable. &lt;strong&gt;You and future developers will thank you many times over.&lt;/strong&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  How to write a TypeScript custom hook for a React Context
&lt;/h3&gt;

&lt;p&gt;Now that we've explored how to add a type to the context, and enforce that a provider is used, it has become a bit cumbersome to actually use the context. We can fix that by creating a custom hook that calls &lt;code&gt;useContext&lt;/code&gt; for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;ThemeState&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;themeState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;themeState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Theme state not found. Try wrapping a parent component with &amp;lt;ThemeContext.Provider&amp;gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;themeState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we have a reusable hook called &lt;code&gt;useTheme&lt;/code&gt; that lets us access the current theme from anywhere. It guarantees that we consistently check if there is a theme provider, and it also removes the dependency on the &lt;code&gt;ThemeContext&lt;/code&gt; variable, which makes the code a bit shorter and easier to change if we want to switch how the theme state is accessed. &lt;strong&gt;Context is now an implementation detail of getting the theme.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, our &lt;code&gt;CurrentThemeDisplay&lt;/code&gt; component from before is much simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;CurrentThemeDisplay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to update state in a context
&lt;/h3&gt;

&lt;p&gt;So far, we've only covered read-only contexts that don't allow consumers to update the state of the context. But it is also possible to provide functions in the context that actually allow the state of the context to change. Using the theme example, let's add a function to change the current theme.&lt;/p&gt;

&lt;p&gt;First, we need to add an additional type for the theme state, plus a callback to change the state. Why do we need to declare it separately? Because we are going to define the state and the callback separately before combining them into the context value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThemeState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThemeStateWithCallbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The current theme state&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ThemeState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Callback for any consumer to change the current theme state&lt;/span&gt;
  &lt;span class="nl"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ThemeState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeStateWithCallbacks&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, to actually store the state and create a callback to change it, we will use &lt;code&gt;React.useState&lt;/code&gt; which conveniently does exactly that for us. To use a hook though, we need to create a component for the provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PropsWithChildren&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the separate theme state type with &lt;code&gt;useState&lt;/code&gt; to define both the current state and create a callback to change it. Then, our theme context simply expects an object that has both a &lt;code&gt;theme&lt;/code&gt; property and &lt;code&gt;setTheme&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Now, because we are using &lt;code&gt;useState&lt;/code&gt;, if any consumer changes the current theme, &lt;code&gt;ThemeProvider&lt;/code&gt; will rerender and broadcast the change to all context consumers of the theme state.&lt;/p&gt;

&lt;p&gt;(NOTE: For this simple case, &lt;code&gt;useState&lt;/code&gt; is sufficient to meet our needs. However, in larger applications, I would strongly&lt;br&gt;
recommend taking a look at &lt;code&gt;&lt;a href="https://reactjs.org/docs/hooks-reference.html#usereducer"&gt;useReducer&lt;/a&gt;&lt;/code&gt; to make&lt;br&gt;
complex state changes simpler and easier to test.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Context is a simple, but powerful feature that can be used in any React project. In this post, we looked at the problems that Context solves, and how to use the React Context API to solve those problems. By adding TypeScript types, we can dramatically improve the type safety when using a context. Furthermore, we can also write a custom hook to ensure that we use the context consistently and safely, as well as make it easier to use.&lt;/p&gt;

&lt;p&gt;If this guide helped you understand how to use React Context and TypeScript better, let me know and tweet me at &lt;a href="https://twitter.com/cammchenry"&gt;@cammchenry&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>react</category>
    </item>
  </channel>
</rss>
