<?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: Robin Pokorny</title>
    <description>The latest articles on DEV Community by Robin Pokorny (@robinpokorny).</description>
    <link>https://dev.to/robinpokorny</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%2F195106%2Fa886958c-deeb-43ec-bd2d-addf98ca6dc7.jpeg</url>
      <title>DEV Community: Robin Pokorny</title>
      <link>https://dev.to/robinpokorny</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robinpokorny"/>
    <language>en</language>
    <item>
      <title>Supermarket Meeting: The Secret to Cutting Down Useless Meetings</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Thu, 12 Sep 2024 10:17:13 +0000</pubDate>
      <link>https://dev.to/robinpokorny/supermarket-meeting-the-secret-to-cutting-down-useless-meetings-co6</link>
      <guid>https://dev.to/robinpokorny/supermarket-meeting-the-secret-to-cutting-down-useless-meetings-co6</guid>
      <description>&lt;p&gt;Meetings. Whoever you are, I’m sure this word brings an emotional response.&lt;/p&gt;

&lt;p&gt;Maybe you see them as a way to reach agreement, maybe you hate them with a passion, maybe you view them as a necessary evil. Maybe you even see them as a welcome break in your workday, maybe you think your reports see them like a welcome break.&lt;/p&gt;

&lt;p&gt;Over the years, I’ve experienced meetings across the entire spectrum of quality, usefulness, and engagement. Some of my career bests have happened in meetings, and so have some of my worst moments.&lt;/p&gt;

&lt;p&gt;The main rule I’ve developed for meetings is simple: &lt;strong&gt;When you’re there, be present.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That means no browsing, no Slack, no coding while the meeting lasts. If the meeting is bad, you have three options: actively make it better, call it out, or just leave. But when I’m there, I want to use the time as effectively as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Supermarket Over the Specialized Shop
&lt;/h2&gt;

&lt;p&gt;When I plan my week or day, I want meetings to use the time they’re scheduled for—not more, not less. I dislike going overtime just as much as I dislike when the host suddenly ‘gives me 20 minutes back.’ On the same note, it’s annoying to receive a cancellation email for lack of topics just an hour before the start of a weekly meeting.&lt;/p&gt;

&lt;p&gt;So when someone suggested a new meeting for a quite specific topic, I shared my concerns. Maybe it would work for the first two three sessions, but eventually, the topics would dry up, and the meeting would die out. Keeping a recurring meeting alive and interesting requires—surprisingly—a lot of work.&lt;/p&gt;

&lt;p&gt;Then I realized we already have some recurring meetings that sometimes end sooner and sometimes get cancelled. It would be much better to expand their purpose to allow related topics. This way, we ensure that the allocated time gets fully used before starting anything new. By making meetings more saturated with diverse topics, we maximize their value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A &lt;strong&gt;Supermarket Meeting&lt;/strong&gt; is a consolidated approach to recurring meetings, where diverse topics are discussed in one weekly session, similar to how you’d buy various items in one trip to the supermarket. Instead of creating multiple specialized meetings for different subjects, a supermarket meeting gathers all related discussions into a single, regular time slot. This maximizes productivity, ensures efficient use of time, and keeps meetings engaging and relevant.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s like a supermarket visit where you buy all your groceries at once, instead of going to specialized shops—baker’s on Mondays, butcher’s on Tuesdays, and a wine shop on Fridays. One meeting, every week, same time, diverse topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  A New Approach to Meetings
&lt;/h2&gt;

&lt;p&gt;From now on, I plan to use a single weekly meeting as a "supermarket" for discussing anything relevant to Tech. A GraphQL schema question? Bring it on! Kafka learnings from your previous job? Sure! DataDog feeding itself quirk? Our inner geeks love that!&lt;/p&gt;

&lt;p&gt;Then, if (or should I write iff?) we often find we don’t have enough time to cover everything, or that some areas would benefit from their own meeting, we’ll create a new slot.&lt;/p&gt;

&lt;p&gt;I’m sure this approach will lead to more engaging meetings while adding some predictability to our schedules. Win, win.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why Developers Should Stop Using ISO 8601 for Date-Time</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Mon, 07 Aug 2023 15:07:42 +0000</pubDate>
      <link>https://dev.to/robinpokorny/why-developers-should-stop-using-iso-8601-for-date-time-2aej</link>
      <guid>https://dev.to/robinpokorny/why-developers-should-stop-using-iso-8601-for-date-time-2aej</guid>
      <description>&lt;p&gt;When documenting APIs, developers often link to &lt;strong&gt;ISO 8601&lt;/strong&gt; as the standard for computer-readable date and date-time format.&lt;/p&gt;

&lt;p&gt;Dates and times (and time zones!) are complicated. There are so many edge cases and pitfalls. I’m sure every developer has a battle story about them. It’s good to delegate that hard work to somebody else. So when an international body that everybody knows and trusts publishes such a standard, it’s no surprise all the API designers start referring to it.&lt;/p&gt;

&lt;p&gt;This is what an &lt;strong&gt;ISO 8601&lt;/strong&gt; date and date-times look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;2023‐08‐07&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;2023‐08‐07T13:25:38Z&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what we want to receive.&lt;/p&gt;

&lt;h3&gt;
  
  
  The ISO allows too much variability and it’s paid to read
&lt;/h3&gt;

&lt;p&gt;Do you know what is also a valid &lt;strong&gt;ISO 8601&lt;/strong&gt; date-time?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;2023-W32-1T15:38+02:00&lt;/code&gt; (= Monday of the 32nd week in my local time zone)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How sure are you that your API will accept such a string? For example, JavaScript’s &lt;code&gt;Date.parse&lt;/code&gt; will fail. There are many more allowed formats in the standard. And support for these is not guaranteed at all.&lt;/p&gt;

&lt;p&gt;If you are thinking about creating a library that will understand all of them, I have bad news for you. There are four versions of the standard, released in the years 1988, 2000, 2004, and 2019, and they are not fully compatible with each other! Plus, you need to pay (about $190) to receive a copy of the standard.&lt;/p&gt;

&lt;p&gt;Fortunately, there is a better way:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;There are two better-suited (and free) standards&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In your documentation, refer to either of these two standards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RFC 3339&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt; (who would’ve guessed?)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of those allows just a small variation of that date-time we want: allowing space instead of &lt;code&gt;T&lt;/code&gt; or not providing some parts. To my knowledge, all of those variations are generally supported. Moreover, the standards are precise and free to read for anybody.&lt;/p&gt;

&lt;p&gt;If you want to be truly strict, I’d also include the format like so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RFC3339 date-time in %Y-%M-%DT%h:%m:%sZ format&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a very clear way to document your API.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Next time, just write RFC 3339 instead&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you find yourself typing ISO 8601 in your code or documentation, just replace it with RFC 3339 and continue knowing you made dates a tiny bit easier for you and your API users.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>programming</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Replace null with ES6 Symbols</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Sat, 24 Jul 2021 12:31:59 +0000</pubDate>
      <link>https://dev.to/robinpokorny/replace-null-with-es6-symbols-3dl</link>
      <guid>https://dev.to/robinpokorny/replace-null-with-es6-symbols-3dl</guid>
      <description>&lt;p&gt;When I was working on my small side-project library, I needed to represent a missing value. In the past, I'd used the nullable approach in simple settings and Option (aka Maybe) when I wanted more control.&lt;/p&gt;

&lt;p&gt;In this case, neither felt correct so I came up with a different approach I'd like to present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Nullable was not enough
&lt;/h2&gt;

&lt;p&gt;Nullable means that when there is a value it is a string, a number, or an object. When there is no value, we use either &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tip:&lt;/em&gt; if you work with nullable types in TypeScript, make sure you turn on the &lt;a href="https://www.typescriptlang.org/tsconfig#strictNullChecks" rel="noopener noreferrer"&gt;&lt;code&gt;strictNullChecks&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is often fine.&lt;/p&gt;

&lt;p&gt;There are, in general, two cases when it's not:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The value &lt;em&gt;can&lt;/em&gt; be &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;. In the end, these are both valid JavaScript primitives and people can use them in many ways.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want to add some advanced logic. Writing &lt;code&gt;x == null&lt;/code&gt; everywhere gets cumbersome.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my case I was handling an output of a Promise, that can return&lt;br&gt;
anything. And I could foresee that both of the ‘missing’ will be eventually returned.&lt;/p&gt;

&lt;p&gt;In general, the problem 1 and 2 have the same solution: use a library that implements the Option type.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Option was too much
&lt;/h2&gt;

&lt;p&gt;Option (sometimes called Maybe) type has two possibilities: either there is no value (&lt;code&gt;None&lt;/code&gt; on &lt;code&gt;Nothing&lt;/code&gt;) or there is a value (&lt;code&gt;Some&lt;/code&gt; or &lt;code&gt;Just&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In JavaScript/TypeScript this means introducing a new structure that wraps the value. Most commonly an object with a property &lt;code&gt;tag&lt;/code&gt; that defines what possibility it is.&lt;/p&gt;

&lt;p&gt;This is how you could quickly implement Option in TypeScript:&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;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&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;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Usually, you would use a library that defines the type and a bunch of useful utils alongside. &lt;a href="https://dev.to/ryanleecode/practical-guide-to-fp-ts-option-map-flatten-chain-6d5"&gt;Here is an intro to Option in my favourite fp-ts library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The library I was building was small, had zero dependencies, and there was no need for using any Option utility. Therefore, bringing in an Option library would be overkill.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/robinpokorny" rel="noopener noreferrer"&gt;
        robinpokorny
      &lt;/a&gt; / &lt;a href="https://github.com/robinpokorny/promise-throttle-all" rel="noopener noreferrer"&gt;
        promise-throttle-all
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🤏 Promise.all with limited concurrency
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;For a while I was thinking about inlining the Option, that is coding it from scratch. For my use case that would be just a few lines. It would complicate the logic of the library a bit, though.&lt;/p&gt;

&lt;p&gt;Then, I had a better idea!&lt;/p&gt;

&lt;h2&gt;
  
  
  Symbol as the new null
&lt;/h2&gt;

&lt;p&gt;Coming back to Nullable, the unsolvable problem is that &lt;code&gt;null&lt;/code&gt; (or &lt;code&gt;undefined&lt;/code&gt;) is global. It is one value equal to itself. It is the same for everybody. &lt;/p&gt;

&lt;p&gt;If you return &lt;code&gt;null&lt;/code&gt; and I return &lt;code&gt;null&lt;/code&gt;, later, it is not possible to find out where the &lt;code&gt;null&lt;/code&gt; comes from.&lt;/p&gt;

&lt;p&gt;In other words, there is ever only one instance. To solve it, we need to have a new instance of &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sure, we could use an empty object. In JavaScript each object is a new instance that is not equal to any other object.&lt;/p&gt;

&lt;p&gt;But hey, in ES6 we got a new primitive that does exactly that: Symbol. (Read some &lt;a href="https://hacks.mozilla.org/2015/06/es6-in-depth-symbols/" rel="noopener noreferrer"&gt;introduction to Symbols&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;What I did was a new constant that represented a missing value, which was a symbol:&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;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`None`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at the benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is a simple value, no wrapper needed&lt;/li&gt;
&lt;li&gt;Anything else is treated as data&lt;/li&gt;
&lt;li&gt;It's a private None, the symbol cannot be recreated elsewhere&lt;/li&gt;
&lt;li&gt;It has no meaning outside our code&lt;/li&gt;
&lt;li&gt;The label makes debugging easier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is great! Especially the first point allows using None as &lt;code&gt;null&lt;/code&gt;. See some example use:&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;isNone&lt;/span&gt; &lt;span class="o"&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;unknown&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;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;None&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasNone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&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="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;None&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;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;S&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;fn&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;T&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;S&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;T&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;None&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="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="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;None&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;None&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fn&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Symbols are almost nulls
&lt;/h2&gt;

&lt;p&gt;There are some disadvantages, too.&lt;/p&gt;

&lt;p&gt;First, which is IMO rare, is that the environment has to &lt;a href="https://caniuse.com/mdn-javascript_builtins_symbol" rel="noopener noreferrer"&gt;support ES6 Symbols&lt;/a&gt;. That means Node.js &amp;gt;=0.12 (not to be confused with v12).&lt;/p&gt;

&lt;p&gt;Second, there are problems with (de)serialisation. Funnily, Symbols behave exactly like &lt;code&gt;undefined&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="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="na"&gt;y&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; "{}"&lt;/span&gt;

&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nc"&gt;Symbol&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; "[null,null]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the information about the instance is, of course, lost. Yet, since it then behaves like &lt;code&gt;undefined&lt;/code&gt;—the native ‘missing value’)—makes it well suited for representing a custom ‘missing value’.&lt;/p&gt;

&lt;p&gt;In contrast, Option is based on structure not instances. Any object with a property &lt;code&gt;tag&lt;/code&gt; set to &lt;code&gt;none&lt;/code&gt; is considered None. This allows for easier serialisation and deserialisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I'm rather happy with this pattern. It seems it's a safer alternative to &lt;code&gt;null&lt;/code&gt; in places where no advanced operations on the property are needed.&lt;/p&gt;

&lt;p&gt;Maybe, I'd avoid it if this custom symbol should leak outside of a module or a library.&lt;/p&gt;

&lt;p&gt;I especially like that with the variable name and the symbol label, I can communicate the domain meaning of the missing value. In my small library it represents that the promise is not settled:&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;notSettled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`not-settled`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Potentially, there could be multiple missing values for different domain meanings.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let me know what you think of this use? Is it a good replacement for &lt;code&gt;null&lt;/code&gt;? Should everybody always use an Option?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note: Symbols are not always easy to use, watch my talk &lt;em&gt;Symbols complicated it all&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/YrQ_ecirpDA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dictator paradox: Why micromanagement is so tempting</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Tue, 25 May 2021 21:34:13 +0000</pubDate>
      <link>https://dev.to/robinpokorny/dictator-paradox-why-micromanagement-is-so-tempting-10bl</link>
      <guid>https://dev.to/robinpokorny/dictator-paradox-why-micromanagement-is-so-tempting-10bl</guid>
      <description>&lt;p&gt;I firmly believe all creative people hate when others tell them what to do. When instead of problems to solve, they are handled solutions to implement or, even worse, isolated tasks to just complete.&lt;/p&gt;

&lt;p&gt;Yet, the world is full of micromanagers.&lt;/p&gt;

&lt;p&gt;Over my career, I’ve heard countless complaints about how managers do not give their reports enough context, enough trust, enough freedom. That they decide all on their own.&lt;/p&gt;

&lt;p&gt;Why is that?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Because micromanagement gets the thing done faster.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, kind of. Let me explain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dictators and complex systems
&lt;/h3&gt;

&lt;p&gt;Originally a &lt;a href="https://en.wikipedia.org/wiki/Roman_dictator"&gt;dictator&lt;/a&gt; (a micromanager is a local dictator) was a role in Ancient Rome, giving almost unlimited power to a selected individual during wartime. The appointment was for emergencies only and it was time-limited.&lt;/p&gt;

&lt;p&gt;The idea was that one person would hold all the important information in their head and, because of that, they will make educated decisions fast. And during the war, a good decision today trumps a better decision tomorrow.&lt;/p&gt;

&lt;p&gt;Having a dictator was actually very smart.&lt;/p&gt;

&lt;p&gt;At wartime.&lt;/p&gt;

&lt;p&gt;You see, a war (or a company, or a software system) is an example of a complex &lt;a href="https://www.goodreads.com/book/show/42360533-thinking-in-systems"&gt;system&lt;/a&gt;. One crucial property of a complex system is that nobody can have a mental model of it that is complete.&lt;/p&gt;

&lt;p&gt;That is, there were things (probably loads of things) that the Roman dictator did not count with and which harmed the people later. But, again, during the war, all is sacrificed towards winning it. Obviously, losing the war would harm all the citizens much more.&lt;/p&gt;

&lt;p&gt;In other words, &lt;strong&gt;a dictator is a reasonable solution if fixing a single problem is all that matters&lt;/strong&gt;. A dictator heavily favors a short-term solution over a long-term solution.&lt;/p&gt;

&lt;p&gt;That is never the case in the real world of software engineering. While there are strict deadlines, meeting them with an exhausted team that is unable to continue is not acceptable. Neither is sacrificing the quality and maintainability of the architecture.&lt;/p&gt;

&lt;p&gt;The project you are working on, however important it seems, cannot jeopardize the ability of the team to continue tackling the next projects. This includes piling the technical debt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is that a paradox?
&lt;/h3&gt;

&lt;p&gt;What I write might seem clear and obvious (I hope it is!). So, where is the paradox?&lt;/p&gt;

&lt;p&gt;I define the &lt;strong&gt;Dictator paradox&lt;/strong&gt; as the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Given a set of projects, every single project alone will be finished faster with a dictator. However, to finish all of the projects, decentralization and coöperation will beat any dictator.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the reason why people talk about self-organized teams, incremental delivery, and emergent design.&lt;/p&gt;

&lt;p&gt;This is why the industry has replaced Waterfall with Agile development.&lt;/p&gt;

&lt;p&gt;This is also why when the pressure makes a manager forget the context and perspective, they will start to micromanage.&lt;/p&gt;

&lt;p&gt;After all: &lt;em&gt;A dictator is a reasonable solution if fixing a single problem is all that matters.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>management</category>
      <category>agile</category>
    </item>
    <item>
      <title>TypeScript Enums I Want to Actually Use</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Sun, 18 Apr 2021 20:16:28 +0000</pubDate>
      <link>https://dev.to/robinpokorny/typescript-enums-i-want-to-actually-use-1cpi</link>
      <guid>https://dev.to/robinpokorny/typescript-enums-i-want-to-actually-use-1cpi</guid>
      <description>&lt;p&gt;Since the very first moment I learned about TypeScript, I knew there's gonna be this one thing I'll always hate: &lt;em&gt;Enums&lt;/em&gt;. So un-elegant, so old-school, and so why-do-you-pollute-my-runtime.&lt;/p&gt;

&lt;p&gt;Well, I was wrong. I use Enums now. At least some of them.&lt;/p&gt;

&lt;p&gt;Let me show you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Enum in TypeScript
&lt;/h2&gt;

&lt;p&gt;First, let's quickly talk about what are Enumerators, or Enums for short.&lt;/p&gt;

&lt;p&gt;An Enum in TypeScript is &lt;strong&gt;a well-defined collection of a limited number of cases&lt;/strong&gt;. That is, we write down all possibilities and do not allow anything else.&lt;/p&gt;

&lt;p&gt;The meaning of enumerations is that in the code you deal with only these few cases and you can be sure to deal with all of them. The compiler will warn if you forget to handle one or more.&lt;/p&gt;

&lt;p&gt;Here are some common enumeration examples to give you a bette idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Directions: &lt;code&gt;North&lt;/code&gt;, &lt;code&gt;South&lt;/code&gt;, &lt;code&gt;East&lt;/code&gt;, &lt;code&gt;West&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CardRanks: &lt;code&gt;Ace&lt;/code&gt;, &lt;code&gt;King&lt;/code&gt;, &lt;code&gt;Queen&lt;/code&gt;, &lt;code&gt;Jack&lt;/code&gt;, &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;9&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;7&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;DateFormats: &lt;code&gt;Unix&lt;/code&gt;, &lt;code&gt;ISO&lt;/code&gt;, &lt;code&gt;Email&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I'll be using countries my app supports as an example. This is how you write enums in TypeScript:&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;Country&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Germany&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;USA&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 is almost like a simple object. Notice that there is no equal sign, this is not an assignment. The definition looks similar to the definition of an interface.&lt;/p&gt;

&lt;p&gt;There is one interesting property of an Enum: it defines both types and values. See some use here:&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;Country&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Germany&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;USA&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;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;//                               ^^^ this is a type&lt;/span&gt;

  &lt;span class="c1"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//               ^^^ this is a value&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&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;&lt;a href="https://www.typescriptlang.org/play?#code/KYOwrgtgBAwg9mEAXATgTygbwFBSgcWBQgEMQ0AaXKAZQHdgATUKvAVRoEEqBfavAYLzYAxnBABnJFAnAknEUgCWAN2DxEqDAF4oACjGb0ALlgJk6AJRRtAPizUA9I6Gu37oQD1vUJAAslCShAqBJfNAAHYGonF0Y4GTgIOQCQAHNsPmxZeUVVdXMtPQ0LNAA6eiZQS1iPQW9PXwCgkLCVEgAbMGjsZygAASQJAFpgAA8oxVGUFDgUbLkFZTUSooByGgBRNcsgA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: I use &lt;code&gt;@ts-expect-error&lt;/code&gt; in the code examples to mark there is a TypeScript error on the next line. This also suppresses the error, so you will not see it in the playground. Remove the line to see the error reported.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's wrong with Enums
&lt;/h2&gt;

&lt;p&gt;Right, that sounds kind of nice, what is the problem?&lt;/p&gt;

&lt;p&gt;There are three main points, I've held against Enums since day one.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Enums introduce (ugly) runtime code
&lt;/h3&gt;

&lt;p&gt;If you want to have a value available, it means that the value has to be there during runtime. That means Enums are one of the very few (and probably the only regularly used) TypeScript constructs that generate some code in the resulting JavaScript.&lt;/p&gt;

&lt;p&gt;Usually, when the target is the current ECMAScript, all type definitions and annotations are just removed. That is because all other constructs like object literals, functions, or classes are the same in JavaScript as in TypeScript.&lt;/p&gt;

&lt;p&gt;Look at how the &lt;code&gt;Country&lt;/code&gt; Enum, defined above, ends up as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Germany&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&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="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Germany&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sweden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&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="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sweden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&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="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USA&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;Country&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Enums are number-based by default
&lt;/h3&gt;

&lt;p&gt;Do you see that code? Do you see those numbers 0, 1, and 2?&lt;/p&gt;

&lt;p&gt;That is the actual value assigned to the country. So while you work with nice names, they are translated to numbers.&lt;/p&gt;

&lt;p&gt;The generated code is practically equal to the following dictionary object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Germany&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;Sweden&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;USA&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So when you want to debug your code and you log the country your function received, you get a cryptic number. Then you need to go and see the relevant version of the source code in TypeScript, count that number from the top, and then you have the name you actually wanted in the first place. Ugh, that is bad.&lt;/p&gt;

&lt;p&gt;Another problem is that you can pass a number where &lt;code&gt;Country&lt;/code&gt; type is expected. A maintenance headache about to happen on its own. But, you can actually pass &lt;em&gt;any&lt;/em&gt; number, irrespective if it is defined in the Enum or not. Both of these calls &lt;a href="https://www.typescriptlang.org/play?target=99&amp;amp;strict=true#code/KYOwrgtgBAwg9mEAXATgTygbwFBSgcWBQgEMQ0AaXKAZQHdgATUKvAVRoEEqBfbbAMZwQAZyRQRwJJwFIAlgDdg8RKgwBeKAAohq9AC5YCZOgCUUdQD4s1APS2ojOBLgQpACzkgA5tj7ZJaVlFZWM1LQBGUwCpGXklFRM0SIAGFNMgA"&gt;will pass the type check&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="nf"&gt;setActiveCountry&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="c1"&gt;// 1 for Sweden&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 100 for ???&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, an Enum should be just a unique value. And the developer should not care about the runtime value and treat the Enum as opaque. However, the whole translation to numbers feels very old-school, a reminder of times where memory was expensive and numbers were used as a means of saving it.&lt;/p&gt;

&lt;p&gt;I know there is a solution with string Enums (we will talk about them in a bit). Yet, I do not understand why the values could not be equal to the labels which are unique already. Or, when the target is ES2015+, the values could be Symbols – using them at a place they were created for.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Enums are not needed in TypeScript
&lt;/h3&gt;

&lt;p&gt;Do you have to use Enums in TypeScript?&lt;/p&gt;

&lt;p&gt;No, there are other ways to type a limited number of cases.&lt;/p&gt;

&lt;p&gt;I see people avoiding Enums in many ways. Either on purpose or out of habit. And, of course, you do not &lt;em&gt;need&lt;/em&gt; them to write good code.&lt;/p&gt;

&lt;p&gt;Before I show you how I'm using Enums now so that I'm comfortable with them, let's explore these common alternatives and discuss their pros and cons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives to Enums
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Disjoint union of literal types
&lt;/h3&gt;

&lt;p&gt;A rather straightforward option is to define a type that consists of all the actual strings (or other values) that are permitted. This is called disjoint or discriminated union; see &lt;a href="https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions"&gt;Discriminated Unions&lt;/a&gt; in TypeScript docs.&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;Country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DE&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="s1"&gt;SE&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="s1"&gt;US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CZ&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;&lt;a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBAwg9gVwHbAE4igXigcgCICiOUAPrgMpGm4Cq5OAUFMy6ywwMZxIDOwUPCMACCHYAEsAbhHjI0GbAAouc9AC5YiFOgCUWAHxQA3kygB6M1AAmcAXAC2QgBbikAcwYBfBg0EixUjJa8oo4lDg6PhZQAALAPAC0EAAekGJJqKhwqL5CohLSstogoTAAWhFAA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see this approach correctly types the function. The problem is that there are ‘magic’ strings all over the place. Sure, for my example the strings are actually somewhat self-explanatory. But let's imagine that instead of &lt;a href="https://en.wikipedia.org/wiki/ISO_3166-1"&gt;ISO 3166-1&lt;/a&gt; two-letter country codes we would be using &lt;a href="https://en.wikipedia.org/wiki/ISO_3166-1_numeric"&gt;ISO 3166-1 numeric&lt;/a&gt; country codes:&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;Country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;276&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="s1"&gt;752&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="s1"&gt;840&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;752&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;203&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;&lt;a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBAwg9gVwHbAE4igXigcgEwDsAbDlAD64ECsepFOAHACwAMOAUFF9z9+wMZwkAZ2BRhEYAEF+wAJYA3CPGRoM2ABSDV6AFyxEKdAEosAPigBvTlAD0tqABM44uAFtJACzlIA5uwBfdnYJaVlFZUM1DRxqWmNg+ygAAWBhAFoIAA9IWUzUVDhUEMkZeSUVIxAYvBYAZhxjIA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While technically equivalent to the previous, this is now utterly unreadable and error-prone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disjoint union of iteral types with constants
&lt;/h3&gt;

&lt;p&gt;What can we do to remove those ‘magic’ strings? Let's save the values to constants:&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;GERMANY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;276&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SWEDEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;752&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;USA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;840&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CZECHIA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;203&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;276&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="s1"&gt;752&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="s1"&gt;840&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SWEDEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CZECHIA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/MYewdgzgLgBA4gUQEoFkCCA5AmjAvDAcgCYB2ANgIChRJYBlAdQQBEEM9CSBWIqm6GAFU6aDgQAcAFgAMfcAIDCALQQKAEgElR+YtIDMVSlACeABwCmMBSACuYKACdjY0hRgAfTjwIfCU2ZQwQcEhwdTysBDmUGjAUACWAG7m1naOzvgAFKBpTgBcVrb2TgCUeAB8MADegTAA9HUwACYgMBAgALbRABbxYADmlAC+lJRRMXFJKUXpmYwsbCWjDTAAAlAQALTmAB4WcdsODiAOY9GxCcmpxcaZyqqaaCVAA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, that sure is better. The constant's name tells the developer what they work with.&lt;/p&gt;

&lt;p&gt;This is, in fact, a way that is popular in the Redux community for Redux actions (Or, should I say &lt;a href="https://phryneas.de/redux-typescript-no-discriminating-union"&gt;was popular&lt;/a&gt;?).&lt;/p&gt;

&lt;p&gt;Still, we can identify problems. First, nothing forces you to use these constants. So if it slips the usually meticulous reviewer's eye, you can end up with a mixed approach: constants and magic strings. Second, the code is not very elegant, we either have to repeat the value in the type definition or use a strange-looking &lt;code&gt;typeof&lt;/code&gt; operators. In either way, adding or removing means a change in two places.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constant dictionary
&lt;/h3&gt;

&lt;p&gt;Hmm, maybe there is a way to combine them all in one. When we look at the code generated for an Enum, we might think: can we just use that dictionary in the first place?&lt;/p&gt;

&lt;p&gt;This works. And it is really close to 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;const&lt;/span&gt; &lt;span class="nx"&gt;Country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Germany&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;USA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;US&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Country&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;Country&lt;/span&gt;&lt;span class="p"&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;Country&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;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CZ&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;&lt;a href="https://www.typescriptlang.org/play?ssl=16&amp;amp;ssc=23&amp;amp;pln=1&amp;amp;pc=1#code/MYewdgzgLgBAwiArmKAnAnjAvDA3gKBhgHEBTVAWwEMx0AuGAcgBEBRRgGkJgGUB3UgBNSYBox7suRAKo8AgmNmd8AXxhUIMUJCj58UdAAdS8JCgzYYB4yABmp5GnQBtANal0dq0dJeEjjABdAG5uInCIonxtaBgIUig5YCgASwA3Un9zTBwAClAA+gdsgEpsAD48bgB6aphBEDiQCgSACxSwAHNVPXjE5PTMsydcrKcAOn4hERK9WpgAASgIAFpSAA9jZLXUVBBUfD6k1IyxjFzGOAAtRhKgA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Weel, it's not terrible. But it's not great either.&lt;/p&gt;

&lt;p&gt;Let me go through some points to keep in mind.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The dictionary has to be declared &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions"&gt;&lt;code&gt;as const&lt;/code&gt;&lt;/a&gt;. This prevents the type engine to infer the type as general dictionary &lt;code&gt;Record&amp;lt;string, string&amp;gt;&lt;/code&gt;. This is OK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Country&lt;/code&gt; dictionary is a value and not a type. We need to define the type separately. It's a cryptic command, one I always have to google – not so OK. Fortunately, the type can be named the same as the dictionary, so from now on it's the same as Enum, right? Well, no.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As in the previous case, nothing truly ties the dictionary to the function arguments. Calling &lt;code&gt;setActiveCountry('SE')&lt;/code&gt; raises no error. The &lt;code&gt;Country&lt;/code&gt; type is, in the end, just another disjoint union of iteral types again. The benefit is that changes are made only in one place. This is Boo (or at least Meh).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enums &lt;del&gt;the right way&lt;/del&gt; my way
&lt;/h2&gt;

&lt;p&gt;For years, I'd been using the previous techniques to avoid Enums.&lt;/p&gt;

&lt;p&gt;And then one day on one PR someone asked: ‘Why?’.&lt;/p&gt;

&lt;p&gt;I was in the middle of my reply when I decided to fact-check some points and, …, and I discovered how wrong I'd been. There were two important properties of Enums that made them &lt;em&gt;superior&lt;/em&gt; to anything else. Even for people that worry about moving back to vanilla JavaScript one day.&lt;/p&gt;

&lt;h3&gt;
  
  
  String Enums
&lt;/h3&gt;

&lt;p&gt;Instead of depending on the source code order to define the value of an option in an Enum, you can define it yourself.&lt;/p&gt;

&lt;p&gt;The following code is so close to the dictionary example above, just much cleaner.&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;Country&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Germany&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Sweden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;USA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;US&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CZ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&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;&lt;a href="https://www.typescriptlang.org/play?ssl=1&amp;amp;ssc=1&amp;amp;pln=18&amp;amp;pc=1#code/KYOwrgtgBAwg9mEAXATgTygbwFBSgcWBQgEMQMBeKAcgBEBRagGlygGUB3YAE1CiuptGLPAFU2AQX41xzbAF9WeZSrzYAxnBABnJFG3AkE9UgCWAN2DxEqSlAAUmm+gBcsBMnQBKfgD4srAD0gVDccPpwEIYAFqYgAOYK2NgGRiYWVh629taeaAB0nDygXsnBUAACSNoAtMAAHgAOwCZ1KChwKCmGxmaWudnUMABa1KXY5VW1Dc2tRB1dqb0ZA+j2goylQA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, let's discuss some more or less obvious observations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It uses equal sigs, not colons. Do not ask me why. Still, it's very close to object literal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The values must be all strings. Other values are not supported. (Technically, numbers can be used, but they bring no advantage. Stick to strings.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You have to use the Enum values anywhere (for example &lt;code&gt;Country.Sweden&lt;/code&gt;) where an Enum value is expected. Passing the same string doesn't work (for example &lt;code&gt;'SE'&lt;/code&gt;). This makes refactoring a headache-free process. And your codebase stays consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;However, it's not all unicorns and rainbow. The generated code is a) still there and b) still (kind of) ugly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;‘How on earth you want to improve that, Robin?’ you might ask&lt;/p&gt;

&lt;p&gt;You're in for a treat.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constant, string Enums
&lt;/h3&gt;

&lt;p&gt;The second improvement that helped me cross the Enum Rubicon (‘The type is cast!’, sorry, sorry, I had to) is constant Enum or &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html#const-enums"&gt;const Enum&lt;/a&gt; for short.&lt;/p&gt;

&lt;p&gt;How does it look 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;const&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Country&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Germany&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Sweden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;USA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;US&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Sweden&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CZ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// @ts-expect-error&lt;/span&gt;
&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&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;&lt;a href="https://www.typescriptlang.org/play?#code/MYewdgzgLgBApmArgWxgYRIsUBOBPGAbwCgYYBxOHZAQzAIF4YByAEQFFmAaUmAZQDucACYIYTZn048yAVT4BBcS3ndiAX15ltOssVCRYEOFAXAoASwBucDFlyMYAClD38ALnSZs+AJTiAPiJeAHoQmGEQGAgQZBMACwswAHMNYmJjU3NrW28HJzsfPAA6QREEX3SwmAABKAgAWjgADwAHOHMmnBwQHAyTM0sbQvzmNAAtZkriarrGlvbOqh6+zMGckfwnSU5fIA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait, wait, I'm not pulling your leg.&lt;/p&gt;

&lt;p&gt;It is a letter-to-letter, carbon copy of the previous code, except for the addition of the &lt;code&gt;const&lt;/code&gt; in front of the &lt;code&gt;enum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The functionality is exactly the same, too. Looking at the list items above: 1. is the same, 2. is the same, 3. is the same, 4. is… NOT the same!&lt;/p&gt;

&lt;p&gt;There is no code generated for the const Enum. This is what the output of the previous code look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setActiveCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;country&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;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setActiveCountry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="cm"&gt;/* Sweden */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, all the values are now inlined in the place of use. There is no clue that there ever was an Enum. Except, maybe, for the helpful comment.&lt;/p&gt;

&lt;p&gt;In the end, the result is the same as in the very first alternative we talked about: the disjoint union of literal types. Yet, it is so much easier to use and safer in all regards.&lt;/p&gt;

&lt;p&gt;To summarize, with constant, string Enums you get all the benefits of string Enums (type checking, debuggable, not replaceable by string) and of writing it directly (no extra code).&lt;/p&gt;

&lt;h2&gt;
  
  
  Constant Enums are a one-way street
&lt;/h2&gt;

&lt;p&gt;Before we go next, I need to warn you about const Enums. They are not a drop-in replacement every time.&lt;/p&gt;

&lt;p&gt;What's the issue? There is no way to get a label for a value. You see, there is no dictionary, there is no code generated at all. So if you have value, say &lt;code&gt;'SE'&lt;/code&gt;, and you want its label for logging, &lt;code&gt;Sweden&lt;/code&gt; in this case, you will not be able to.&lt;/p&gt;

&lt;p&gt;That is a small inconvenience, you should keep in mind.&lt;/p&gt;

&lt;p&gt;Also, if you need to access the labels for something else than logging, it might mean that Enum is not for you. Enum labels should have a meaning only for the developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constant Enums can be huge
&lt;/h2&gt;

&lt;p&gt;One great use case I found of constant Enums, is that you do not care about the number of items in an Enum. There could be a const string Enum of all the countries in the world and if you only use there, just these three will make it to the production code. The rest would just disappear. And code autocomplete still works with no issue.&lt;/p&gt;

&lt;p&gt;In our service code, we now have a share const string Enum with all existing HTTP response codes (excerpt):&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;OK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Created&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;201&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// …&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;const&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;ClientError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;BadRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;400&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Unauthorized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;401&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PaymentRequired&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;402&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Forbidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;403&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;NotFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;404&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// …&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// …&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;HttpStatusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;InformationalResponse&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Success&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Redirection&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ClientError&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ServerError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What makes a great Enum
&lt;/h2&gt;

&lt;p&gt;Const string Enums.&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;That is what I now use everywhere.&lt;/p&gt;

&lt;p&gt;Before commit, I make sure each Enum fulfills the following two conditions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All Enum options have a defined custom string value.&lt;/li&gt;
&lt;li&gt;The Enum is declared as &lt;code&gt;const&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think this combines the benefits of TypeScript with the eloquence of pure JavaScript. A superb developer experience with close to zero impact on the result. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do you use Enums in your code? Do you avoid language features that are not considered for ECMAScript? Tweet a reply&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>typescript</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Engineering Managers Should Not Have the Best Tech Skills in Team</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Fri, 19 Mar 2021 21:57:41 +0000</pubDate>
      <link>https://dev.to/robinpokorny/engineering-managers-should-not-have-the-best-tech-skills-in-team-kpi</link>
      <guid>https://dev.to/robinpokorny/engineering-managers-should-not-have-the-best-tech-skills-in-team-kpi</guid>
      <description>&lt;p&gt;Recently I was re-reading one of my favorite engineering articles &lt;a href="https://www.thekua.com/atwork/2019/02/the-trident-model-of-career-development/"&gt;The Trident Model of Career Development&lt;/a&gt; by Patrick Kua. The sentence that caught my eye this time was a note about the role of a Tech Lead:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They should have good but not necessarily the best [tech] skills in the team they are leading.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;‘How does this apply to an Engineering Manager?’&lt;/em&gt; came to my mind instantly. And my initial response was that it's the same. Yet, after some more thought and thinking about the Engineering Managers I've met, I was not sure. Then I made my mind: no, it's not the same. Now, I think that &lt;strong&gt;it is actually dangerous when an Engineering Manager has the best tech skills in the team&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let me show you why.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. They cannot utilize it
&lt;/h2&gt;

&lt;p&gt;Becoming a manager is a big lateral step for an engineer. While they can draw from their tech experience, being a manager requires a very different set of skills, and–what makes it even more challenging–many of these will be completely new for them. There are so many activities that are not coding, reviewing, or architecting. The new manager simply doesn't have the time to use their tech skills as they did before. That means that the team and the company now lost a significant portion of tech contributions.&lt;/p&gt;

&lt;p&gt;The team is not the only one who is unhappy about it; in fact, and I'll bet on this, the manager is even more unhappy about it themself. In my previous experience, I saw many brilliant senior engineers who wanted to grow and become an Engineering Manager seemed so natural. Often they were told that the new responsibility will only mandate 10 or 20 % of their time. What a lie that was, as they soon found out.&lt;/p&gt;

&lt;p&gt;There were three outcomes I've witnessed: not many of the managers accommodated and let the tech go (at least partially); some felt guilty and coded in overtime; and quite a few decided that management was not for them and went back to senior engineers. (A side note for the last case: since becoming an Engineering Manager is often seen as a promotion, most of them rather left the company and applied to a senior engineering position elsewhere.)&lt;/p&gt;

&lt;h2&gt;
  
  
  2. They will be a bottleneck
&lt;/h2&gt;

&lt;p&gt;Connected closely to the previous point, the team might be waiting for code contributions, PR reviews, or comments on RFCs longer.&lt;/p&gt;

&lt;p&gt;The number one comment I hear from new managers is about the number of meetings they are expected to attend. This not only deducts from their hours in a day directly but because of the workday fragmentation and constant context switching it is more difficult to find a longer time for uninterrupted work in between the meetings.&lt;/p&gt;

&lt;p&gt;This will become a big issue when the task is extremely time-sensitive, like when there is an incident and the best person available should lead the detailed debugging. While avoiding huge losses for the company, the manager will build up a personal debt of materials they need to read, meeting recordings they need to watch, and postponed decisions they need to make.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. They will cause sub-optimal decisions
&lt;/h2&gt;

&lt;p&gt;Speaking of decisions, there is a significant risk that the team will make some bad tech decisions. Or at least not as good decisions.&lt;/p&gt;

&lt;p&gt;Why? In simple words, it's difficult to disagree with the person who evaluates your performance and decides on your salary, bonuses, and promotions. This whole desire to please one's superior might very well be subconscious. Yet, it creates a disbalance that might result in worse tech decisions made.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are some great stories about preconceptions the managers had to fight in Kim Scott's &lt;a href="https://www.radicalcandor.com/the-book/"&gt;Radical Candor&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'm not saying that it is not possible to avoid it, but it requires that the manager is aware and puts some compensation processes in place. They also have to work on increasing the level of psychological safety among the team members.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should I do when this is my case?
&lt;/h2&gt;

&lt;p&gt;Are you a manager that has the best tech skills in the team? Do you wonder what to do next?&lt;/p&gt;

&lt;p&gt;First, this is a fairly common scenario and I know many teams like that that work just fine. The key is to acknowledge that there are some potential risks and be vigilant about their signs.&lt;/p&gt;

&lt;p&gt;The best, however, is to stop being the tech go-to expert in the team. Of course, that doesn't mean you should become worse or leave your manager post. It means actively working on growing your report's skills. It means extensive knowledge sharing. It means grooming your successor (or successors).&lt;/p&gt;

&lt;p&gt;Lastly, you should become comfortable in your position. Accepting and embracing that there will be people better than you in technology, in skills you've been so proud to possess. Knowing that the value you bring has shifted from individual strengths to multiplying strengths of others.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Are you an engineering manager that balances tech and people skills? Who do you think should be best at tech in a team? Tweet a reply&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Related articles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.toptal.com/engineering-team-manager/engineering-manager-role-explained"&gt;People, Product, and Technology: A Beginner’s Guide to Engineering Management&lt;/a&gt; at Toptal blog&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.thekua.com/atwork/2019/02/the-trident-model-of-career-development/"&gt;The Trident Model of Career Development&lt;/a&gt; by Patrick Kua&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.patkua.com/blog/5-engineering-manager-archetypes/"&gt;5 Engineering Manager Archetypes&lt;/a&gt; by Patrick Kua&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>leadership</category>
      <category>management</category>
    </item>
    <item>
      <title>Are open-source databases dead? [Quora answer]</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Fri, 05 Mar 2021 19:36:47 +0000</pubDate>
      <link>https://dev.to/robinpokorny/are-open-source-databases-dead-quora-answer-2843</link>
      <guid>https://dev.to/robinpokorny/are-open-source-databases-dead-quora-answer-2843</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is an answer to a Quora question: &lt;a href="https://www.quora.com/Are-open-source-databases-dead/answer/Robin-Pokorn%C3%BD"&gt;Are open-source databases dead?&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, they are dying (this is no joke answer).&lt;/p&gt;

&lt;p&gt;Sure, many open-source databases are being used and maintained every day. And, of course, any open-source software will exist and can be forked by anybody. So on the technical level, they cannot die.&lt;/p&gt;

&lt;p&gt;However, we have seen several big open-source databases die in the past years. MongoDB, Redis, CockroachDB, TimescaleDB, and–most recently–Elasticsearch. All of those databases ceased to be open-source.&lt;/p&gt;

&lt;p&gt;Let me show it on the example of MongoDB and Elasticsearch. Both of the companies behind the databases decided to switch to Server Side Public License (SSPL) which is not considered to be an open-source license. Since this license allows free (as in beer) use for &lt;em&gt;some&lt;/em&gt; use cases we will likely be seeing them for quite some time. It’s nevertheless a death of an open-source project.&lt;/p&gt;

&lt;p&gt;The reason cited by both projects is… Amazon. More specifically AWS. You see, Mongo and ES were developed by companies and these companies not only lead the project development, but they also hold the trademarks etc. They both also make money on providing some services for their DB, be it consulting, paid extensions, or DBaaS (database-as-a-service) hosting. Historically, publishing open-source software and making money on the services worked great and for many companies, it was a viable business strategy (yes, open source is a business strategy).&lt;/p&gt;

&lt;p&gt;In the world of AWS (and other cloud providers) it creates an asymmetrical relationship: AWS can provide and charge for their DBaaS based on an open-source database while paying nothing back to Mongo or Elastic (Amazon has the manpower to support it themselves even on large scale). Which is completely OK under the open-source licenses.&lt;/p&gt;

&lt;p&gt;Both of those companies realised that their business strategy was wrong and open-sourcing their DB was a mistake (from the business point of view). So they changed the license to a non-free (as in speech) and non-open one. This created some controversy as relicensing open-source is generally not possible, they took advantage of a clause in CLA that every contributor had to sign.&lt;/p&gt;

&lt;p&gt;(Side note, this lowered already low trust in CLAs. A problem for some mostly big companies, that feel they need some extra intellectual property protection and still want to have an open-source program.)&lt;/p&gt;

&lt;p&gt;If I were starting a business in providing a database engine now, I’d really think about open-sourcing it based on the experience of Mongo and Elastic. And we see exactly that already, with DBs like Fauna or Firebase not being open-sourced at all.&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;I think that open-source databases are dying&lt;/strong&gt; because we might see less and less of them published in the future.&lt;/p&gt;




&lt;h3&gt;
  
  
  Related articles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.theregister.com/AMP/2021/01/22/aws_elastic_fork/"&gt;And just like that, Amazon Web Services forked Elasticsearch, Kibana. Was that part of the plan, Elastic?&lt;/a&gt; on The Register&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://drewdevault.com/2021/01/19/Elasticsearch-does-not-belong-to-Elastic.html"&gt;Elasticsearch does not belong to Elastic &lt;/a&gt;on Drew DeVault's blog&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.elastic.co/blog/licensing-change"&gt;Doubling down on open, Part II&lt;/a&gt; on Elastic blog&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cockroachlabs.com/blog/oss-relicensing-cockroachdb/"&gt;Why We're Relicensing CockroachDB&lt;/a&gt; on Cockroachlabs blog&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.timescale.com/blog/building-open-source-business-in-cloud-era-v2/"&gt;How we are building a self-sustaining open-source business in the cloud era (version 2)&lt;/a&gt; on Timescale blog&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>elasticsearch</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Index as a key is an anti-pattern</title>
      <dc:creator>Robin Pokorny</dc:creator>
      <pubDate>Fri, 22 May 2020 12:03:16 +0000</pubDate>
      <link>https://dev.to/robinpokorny/index-as-a-key-is-an-anti-pattern-16m1</link>
      <guid>https://dev.to/robinpokorny/index-as-a-key-is-an-anti-pattern-16m1</guid>
      <description>&lt;p&gt;&lt;strong&gt;This article was cross-posted from Medium, please use also the discussion there.&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--va0RGVkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:88:88/1%2A9kmEW8fKloAtfL0spwLiAw.png" alt="Robin Pokorny"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Index as a key is an anti-pattern (React) | by Robin Pokorny | Medium&lt;/h2&gt;
      &lt;h3&gt;Robin Pokorny ・ &lt;time&gt;Aug 4, 2022&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;





&lt;p&gt;So many times I have seen developers use the index of an item as its key when they render a list.&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&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;It looks elegant and it does get rid of the warning (which was the ‘real’ issue, right?). What is the danger here?&lt;/p&gt;

&lt;h1&gt;
  
  
  It may break your application and display wrong data!
&lt;/h1&gt;

&lt;p&gt;Let me explain, a &lt;em&gt;key&lt;/em&gt; is the only thing React uses to identify DOM elements. What happens if you push an item to the list or remove something in the middle? If the &lt;em&gt;key&lt;/em&gt; is same as before React assumes that the DOM element represents the same component as before. But that is no longer true.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5rn0a5ruxia9vzkw2tdz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5rn0a5ruxia9vzkw2tdz.png" alt="Stephen describes the problem he run into on [egghead.io](https://egghead.io/forums/lesson-discussion/topics/break-up-components-into-smaller-pieces-using-functional-components#post-6310)" width="800" height="377"&gt;&lt;/a&gt;&lt;em&gt;Stephen describes the problem he run into on &lt;a href="https://egghead.io/forums/lesson-discussion/topics/break-up-components-into-smaller-pieces-using-functional-components#post-6310"&gt;egghead.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;To demonstrate the potential danger I created &lt;a href="https://jsbin.com/wohima/edit?output"&gt;a simple example&lt;/a&gt; (&lt;a href="http://jsbin.com/wohima/edit?js,output"&gt;with source&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xt_qLq-N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dljslvfla/image/upload/f_auto/v1590063144/1_GFYGPdDFLYcLFzx-E-GEcw_tm1v2m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xt_qLq-N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dljslvfla/image/upload/f_auto/v1590063144/1_GFYGPdDFLYcLFzx-E-GEcw_tm1v2m.jpg" alt="Screenshot of the example showing the danger of using the index as key." width="800" height="375"&gt;&lt;/a&gt;&lt;em&gt;Screenshot of the example showing the danger of using the index as key.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It turns out, when nothing is passed React uses the &lt;em&gt;index&lt;/em&gt; as &lt;em&gt;key&lt;/em&gt; because it is the best guess at the moment. Moreover, it will warn you that it is suboptimal (it says that in a bit confusing words, yes). If you provide it by yourself React just thinks that you know what you are doing which — remember the example — can lead to unpredictable results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better
&lt;/h3&gt;

&lt;p&gt;Each such item should have a &lt;em&gt;permanent&lt;/em&gt; and &lt;em&gt;unique&lt;/em&gt; property. Ideally, it should be assigned when the item is created. Of course, I am speaking about an &lt;em&gt;id&lt;/em&gt;. Then we can use it the following way:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;todo&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; First look at the existing properties of the items. It is possible they already have something that can be used as an &lt;em&gt;id&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One way to do so it to just move the numbering one step up in the abstraction. Using a global index makes sure any two items would have different *id*s.&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="nx"&gt;todoCounter&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createNewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&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;{&lt;/span&gt;
    &lt;span class="na"&gt;completed&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todoCounter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;text&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;h3&gt;
  
  
  Much better
&lt;/h3&gt;

&lt;p&gt;A production solution should use a more robust approach that would handle distributed creation of items. For such, I recommend &lt;a href="https://www.npmjs.com/package/shortid"&gt;shortid&lt;/a&gt;. It quickly generates ‘short non-sequential url-friendly unique’ ids. The code could look like the following:&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;var&lt;/span&gt; &lt;span class="nx"&gt;shortid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shortid&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="nf"&gt;createNewTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&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;{&lt;/span&gt;
    &lt;span class="na"&gt;completed&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shortid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;text&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;h1&gt;
  
  
  &lt;em&gt;TL;DR:&lt;/em&gt; Generate a unique &lt;em&gt;id&lt;/em&gt; for every item and use it as &lt;em&gt;key&lt;/em&gt; when rendering the list.
&lt;/h1&gt;




&lt;h3&gt;
  
  
  Update: Exception from the rule
&lt;/h3&gt;

&lt;p&gt;Many people asked if they always, &lt;em&gt;always&lt;/em&gt; have to generate ids. Others have suggested use cases when using the index as a key seems justifiable.&lt;/p&gt;

&lt;p&gt;It is true that sometimes generating new ids is redundant and may be avoided. For example translation of license terms or list of contributors.&lt;/p&gt;

&lt;p&gt;To help you decide, I put together three conditions which these examples have in common:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the list and items are static–they are not computed and do not change;&lt;/li&gt;
&lt;li&gt;the items in the list have no ids;&lt;/li&gt;
&lt;li&gt;the list is &lt;em&gt;never&lt;/em&gt; reordered or filtered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When &lt;em&gt;all&lt;/em&gt; of them are met, you &lt;strong&gt;may safely use the index as a key&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update 2: React, Preact, and *react
&lt;/h3&gt;

&lt;p&gt;Although in this article I write about React, the problem is not exclusive to it. In similar libraries, like Preact, the danger is present, too. However, the effects can be different.&lt;/p&gt;

&lt;p&gt;See the following StackOverflow question, where the last element disappears. Also please note the explanation in the answers provided by the creator of Preact, Jason Miller: &lt;a href="http://stackoverflow.com/questions/42773892/wrong-components-rendered-by-preact"&gt;Wrong components rendered by Preact&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  References and related articles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://facebook.github.io/react/docs/multiple-components.html#dynamic-children"&gt;Dynamic Children&lt;/a&gt; and &lt;a href="https://facebook.github.io/react/docs/create-fragment.html"&gt;Keyed Fragments&lt;/a&gt; in React Docs&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/issues/1342#issuecomment-39230939"&gt;Explanation from Paul O’Shannessy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://coderwall.com/p/jdybeq/the-importance-of-component-keys-in-react-js"&gt;The importance of component keys in React.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.arkency.com/2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/"&gt;React.js and Dynamic Children — Why the Keys are Important&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://unitstep.net/blog/2015/03/03/using-react-animations-to-transition-between-ui-states/"&gt;React animations for a single component&lt;/a&gt;, section &lt;em&gt;The key is using key&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paulgray.net/keys-in-react/"&gt;Why you need keys for collections in React&lt;/a&gt; by &lt;a href="https://dev.toundefined"&gt;Paul Gray&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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