<?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: Yann L</title>
    <description>The latest articles on DEV Community by Yann L (@ylerjen).</description>
    <link>https://dev.to/ylerjen</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%2F21327%2F164a9bfe-21d0-4e53-88c1-4509c4a2a5c3.jpg</url>
      <title>DEV Community: Yann L</title>
      <link>https://dev.to/ylerjen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ylerjen"/>
    <language>en</language>
    <item>
      <title>Typescript enums drawbacks and solutions</title>
      <dc:creator>Yann L</dc:creator>
      <pubDate>Wed, 22 Dec 2021 12:12:21 +0000</pubDate>
      <link>https://dev.to/ylerjen/use-typescript-const-assertion-instead-of-enums-mfn</link>
      <guid>https://dev.to/ylerjen/use-typescript-const-assertion-instead-of-enums-mfn</guid>
      <description>&lt;p&gt;Typescript has for years an enum feature that is very similar to the C# one. However, when run, Typescript is Javascript and enum have to be transpiled. The result is not so satisfying than what we could expect as it's very verbose. In this article we'll see why it's so verbose and what other solutions can improve our code.&lt;/p&gt;

&lt;h1&gt;
  
  
  The problem of TS enums
&lt;/h1&gt;

&lt;p&gt;Typescript's enums are very handy because there's nothing like enum yet in Javascript, probably because a JS object is very close from an enum already. But when we write TS code, the enum informs about readonly state, which is something that can't be done easily from the object (well this is not true anymore... read further).&lt;/p&gt;

&lt;p&gt;However, at build time, the TS enum has to be transpiled to an object. The result will be a very verbose transpiled output for something that could be simply an object structure. The developer has then to choose between a lighter output by using an object or a better typing comfort by using the enum type...&lt;/p&gt;

&lt;p&gt;Here's a concrete example of enum transpilation in TS &lt;br&gt;
&lt;em&gt;(TSConfig's target = es2017)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;EHttpStatusCode&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="mi"&gt;200&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="mi"&gt;400&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="mi"&gt;401&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="mi"&gt;403&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="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ServerError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&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;will transpile to the following JS&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;EHttpStatusCode&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;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ok&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;200&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;Ok&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BadRequest&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;400&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;BadRequest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unauthorized&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;401&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;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Forbidden&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;403&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;Forbidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NotFound&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;404&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;NotFound&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ServerError&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;500&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;ServerError&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;EHttpStatusCode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EHttpStatusCode&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;p&gt;Pretty verbose isn't it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does Typescript generate all this code?
&lt;/h2&gt;

&lt;p&gt;The reason for that is &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings" rel="noopener noreferrer"&gt;Reverse Mapping&lt;/a&gt;. In short, the reverse mapping allows you to pass the value to the enum to get a literal value.&lt;/p&gt;

&lt;p&gt;The good point of this reverse mapping is that if it was not provided, but we would need it, then we would have to write some logic like following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getEnumKeyByEnumValue&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="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{[&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myEnum&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="nx"&gt;enumValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myEnum&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;myEnum&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;==&lt;/span&gt; &lt;span class="nx"&gt;enumValue&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;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;keys&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="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a cavehat tho, and it's that most of the time we don't need this reverse mapping... So we're basically bloating the bundle with useless code more than we should.&lt;/p&gt;

&lt;h2&gt;
  
  
  String enums have no reverse mapping
&lt;/h2&gt;

&lt;p&gt;Something interesting to know is that string enums are handled differently by the compiler. If you compare a string enum and another type of enum (ex: number), you'll quickly notice that the transpiled code is different for the string value. It's now a simple enum without reverse mapping, but still it's more verbose than a basic javascript object.&lt;/p&gt;

&lt;p&gt;So if you were trying to use reverse mapping on a string enum, then now you know why your code is not working as expected.&lt;/p&gt;

&lt;h1&gt;
  
  
  Alternatives to enums
&lt;/h1&gt;

&lt;p&gt;Verbosity of the transpilation is something that was heard by the TypeScript team and they now offers alternatives:&lt;/p&gt;

&lt;h2&gt;
  
  
  The const assertion feature
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions" rel="noopener noreferrer"&gt;const assertion&lt;/a&gt; feature will help us keep a lighter bundle, but at the same time it will give us the same typing feature than the enum. &lt;/p&gt;

&lt;p&gt;This is how to use it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;declare the object like you would in plain JS&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;as const&lt;/code&gt; after the declaration
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpStatusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Unauthorized&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Forbidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ServerError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this declaration will do, is create the object, but also inform TS that all the properties and the object are readonly.&lt;br&gt;
Talking about the output bundle, the Javascript transpiled result will be exactly the same but without the &lt;code&gt;as const&lt;/code&gt; statement for sure.&lt;/p&gt;
&lt;h3&gt;
  
  
  However we still miss the typing feature
&lt;/h3&gt;

&lt;p&gt;So now yes we have the enum declaration, but we still miss the Type which will be used by TS to type check our code.&lt;/p&gt;

&lt;p&gt;For TS check, we will need 1 more declaration (here below it's an example of how you could try to declare an enum property, but...)&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;class&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpStatusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// other stuff here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This won't work because our object is a value and we can't directly use it as a type. So we will need to extract the type from it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;HttpStatusCodeKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;httpStatusCode&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;type&lt;/span&gt; &lt;span class="nx"&gt;HttpStatusCode&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;httpStatusCode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;HttpStatusCodeKey&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the real type which is representing the union of the &lt;code&gt;httpStatusCode&lt;/code&gt; object's values. And the good news is that this type is only used for building TS and is then removed from the transpiled output. So the only thing JS will have is the object.&lt;/p&gt;

&lt;p&gt;On TS side it will then be very easy to type the code 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;class&lt;/span&gt; &lt;span class="nc"&gt;HttpResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpStatusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;httpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// other stuff here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also notice the casing convention. The object const is camelCased (&lt;code&gt;httpStatusCode&lt;/code&gt;) because it's a value. On the other hand, the type extracted from the object is PascalCased (&lt;code&gt;HttpStatusCode&lt;/code&gt;). So it follows usual convention and is then easy to differentiate type from value object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Const enums
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html#const-enums" rel="noopener noreferrer"&gt;const enum&lt;/a&gt; is exactly the same syntax than a standard enum, but with a const prefix.&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;EHttpStatusCode&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="mi"&gt;200&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="mi"&gt;400&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="mi"&gt;401&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="mi"&gt;403&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="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ServerError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&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;However this slight difference will become a huge one in the transpiled output. See here what will come out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You read it correctly, there's nothing... The reason for that is that the whole enum is now virtual. And when you will use its value, the value will directly be printed instead. It's like a swipe of the enum to a value at compile time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Typescript enum is a C# flavor brought to Typescript. It's an innocent syntax when you're coming from C# code, but it can be harmful to the end user. The typescript authors are also aware of this pitfall and are doing great work to provide alternate solutions. So if you don't know what to use you can follow this logic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do you need reverse mapping? (If you don't know, then the answer is probably "No")&lt;/li&gt;
&lt;li&gt;If Yes, and your enum is not about strings, then you'll have to use a standard enum&lt;/li&gt;
&lt;li&gt;If No, continue to the next point&lt;/li&gt;
&lt;li&gt;Do you need to loop over enum members?&lt;/li&gt;
&lt;li&gt;If Yes, then use const assertion&lt;/li&gt;
&lt;li&gt;If No, continue to the next point&lt;/li&gt;
&lt;li&gt;Use const enum and live happy &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feel free to share your thoughts in the comment 💬 or to like 👍  the post if it was interesting for you.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>enum</category>
      <category>readonly</category>
      <category>optimization</category>
    </item>
    <item>
      <title>Angular library with demo project</title>
      <dc:creator>Yann L</dc:creator>
      <pubDate>Tue, 07 Sep 2021 11:17:01 +0000</pubDate>
      <link>https://dev.to/ylerjen/angular-library-with-demo-project-1i1b</link>
      <guid>https://dev.to/ylerjen/angular-library-with-demo-project-1i1b</guid>
      <description>&lt;p&gt;Angular, with the help of angular-cli makes it easy to create a library project. But when your library is about components, it's very useful to have a visual rendering of what you're creating, and not only the lib code and tests.&lt;br&gt;
In this article, we'll see how we can easily create in a same project, the library and the demo app, but still keep a coherent structure like we need for a library project.&lt;/p&gt;
&lt;h2&gt;
  
  
  Generate the Angular workspace
&lt;/h2&gt;

&lt;p&gt;Like for every Angular project, the first step is to generate the workspace for your library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng new my-lib &lt;span class="nt"&gt;--createApplication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="c"&gt;# for Angular &amp;lt; 16&lt;/span&gt;
ng new my-lib &lt;span class="nt"&gt;--no-create-application&lt;/span&gt; &lt;span class="c"&gt;# for Angular 16+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠ Don't forget the &lt;code&gt;createApplication&lt;/code&gt; option so that you don't generate the skeleton of an app inside of your workspace. We will see later how to organize the project structure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you should see the base Angular workspace, with a &lt;code&gt;project&lt;/code&gt; folder to correctly structurate libraries and demo app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate the library in the project
&lt;/h2&gt;

&lt;p&gt;Angular-cli can generate the library project scaffolding for you with the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate library myLib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have a &lt;code&gt;my-lib&lt;/code&gt; folder inside &lt;code&gt;projects&lt;/code&gt; and that's where you will place all components related to the library you're creating.&lt;/p&gt;

&lt;p&gt;If you open the &lt;code&gt;./tsconfig.json&lt;/code&gt; file, you should also see the &lt;code&gt;path&lt;/code&gt; property that was created with the information about your library. This will be useful later to easily import it from the demo app.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;./tsconfig.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"paths"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"my-lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dist/my-lib/my-lib"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dist/my-lib"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generate the demo app
&lt;/h2&gt;

&lt;p&gt;To generate the demo app, Angular-cli again provide you a command for scaffolding generation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate application demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you noticed, this time, we don't use the &lt;code&gt;library&lt;/code&gt; keyword, but the &lt;code&gt;application&lt;/code&gt; one. The generated project will be different as it can be "started" to be debugged in the browser.&lt;/p&gt;

&lt;p&gt;The difference of using &lt;code&gt;generate application&lt;/code&gt; command, instead of doing this at the first step with &lt;code&gt;ng new my-lib&lt;/code&gt;, is that it allows a workspace name different from the initial app name, and ensures that all applications reside in the /projects subfolder, matching the structure of the configuration file.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;More info in the &lt;a href="https://angular.io/cli/new" rel="noopener noreferrer"&gt;angular-cli documentation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Import the lib in the demo project
&lt;/h2&gt;

&lt;p&gt;Now that you've created the components you wanted in the lib and also the demo project to see your component in the browser, what you're missing is the glue between both.&lt;br&gt;
This link is done by importing your library module into the demo project. As we have seen, the tsconfig was automatically updated with the new path, so now in your project, you just need to specify the import with the path key, like:&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;demo/src/app/app.module.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyLibModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-lib&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;That way, when the build is started, it will detect the &lt;code&gt;my-lib&lt;/code&gt; path, and with the help of the config, it will know where to look for to import the module correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't forget to build
&lt;/h2&gt;

&lt;p&gt;One last thing to consider, is that in this &lt;code&gt;tsconfig.json&lt;/code&gt; file, the path is looking for the &lt;code&gt;dist&lt;/code&gt; folder. But this one doesn't exist yet. This mean that if you want your demo project to find your library components, you will need to build the library first.&lt;/p&gt;

&lt;p&gt;For that purpose, you can add a script in the &lt;code&gt;package.json&lt;/code&gt; file to easily build the lib every time you need it to be updated.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build-lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build my-lib --watch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then simply build the lib with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build-lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧐 If this article helped you in a way, don't hesitate to share it or comment 💬&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Cover image by &lt;a href="https://unsplash.com/@samuelwu" rel="noopener noreferrer"&gt;@samuelwu&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>library</category>
      <category>project</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Typescript cast is a type breaker</title>
      <dc:creator>Yann L</dc:creator>
      <pubDate>Thu, 17 Jun 2021 10:28:51 +0000</pubDate>
      <link>https://dev.to/ylerjen/typescript-cast-is-a-type-breaker-1jbh</link>
      <guid>https://dev.to/ylerjen/typescript-cast-is-a-type-breaker-1jbh</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://unsplash.com/@pankajpatel" rel="noopener noreferrer"&gt;Pankaj Patel on Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Typescript types and "cast"
&lt;/h1&gt;

&lt;p&gt;Everyone is aware that the &lt;code&gt;any&lt;/code&gt; type is a bad thing because it would basically be like coming back to Javascript where there's no strong type check and anything is allowed.&lt;/p&gt;

&lt;p&gt;But even if we respect this rule, we can fall into another pitfal where we break Typescript's type-check by casting types. Following chapter will describe you why and how to avoid it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typing the code
&lt;/h2&gt;

&lt;p&gt;Type creation can be done in several ways in typescript. It can be anonymous, interface/class declarations, type aliases, duck-typings, etc. (See everything &lt;a href="https://www.typescriptlang.org/docs/handbook/2/objects.html" rel="noopener noreferrer"&gt;in the doc&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;But when it comes about typing a variable, there's one syntax only which is with colon :.&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;mystring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// this example could be duck-typed, but yeah, focus on the colon&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By typing a variable, TS will know what type it is, &lt;strong&gt;and check&lt;/strong&gt; that the content of the variable is valid with the given type.&lt;/p&gt;

&lt;p&gt;The following example shows exactly this behavior, the compiler will tell you that your definition is not valid according to the type you've defined.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqu9oami31g4jvvgtc6ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqu9oami31g4jvvgtc6ec.png" alt="Example of type error highlighted by TS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Casting the code
&lt;/h2&gt;

&lt;p&gt;The cast syntax is done either with the &lt;code&gt;as&lt;/code&gt; keyword, or with the angle-bracket notation &lt;code&gt;&amp;lt;...&amp;gt;&lt;/code&gt;. The former being probably better (opinionated) as it can't be confused with the angle bracket notation for generic types.&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;duck&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Duck&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'as' keyword notation&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;duck&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;Duck&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// angle bracket notation&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If instead of typing it, you use a cast, TS will know the type of your object, but &lt;strong&gt;won't make any type check&lt;/strong&gt;, because casting the variable is about saying to TS &lt;em&gt;"Trust me, I know what I'm doing!"&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;The same example casted would then look like following and wouldn't raise any error:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd17zes7ga3fwzt8upxr5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd17zes7ga3fwzt8upxr5.png" alt="A type error not highlighted by Typescript due to the cast"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Needless to say that this type check "break" is where it becomes dangerous and that's why we should not confuse types and casts.&lt;/p&gt;

&lt;p&gt;In fact it was so confusing that even TS developers have added a new feature (the &lt;code&gt;unknown&lt;/code&gt; type described later in this page) to prevent some unwanted casts and force developers to explicitly cast completely different types.&lt;/p&gt;

&lt;h1&gt;
  
  
  When is a cast ok?
&lt;/h1&gt;

&lt;p&gt;Like in every other strongly typed languages, a cast in the code is mostly only about polymorphism.&lt;/p&gt;

&lt;p&gt;Here are some example:&lt;/p&gt;

&lt;h2&gt;
  
  
  You're precising the type with inheritance
&lt;/h2&gt;

&lt;p&gt;Like in other languages, that's basically the reason for a cast. When you have an object of a certain type group and want to precise the exact type because you now know more about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9k3ad5vvw630dvfnsnl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9k3ad5vvw630dvfnsnl.png" alt="Cast to precise inherited object type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  You're precising the type from union types
&lt;/h2&gt;

&lt;p&gt;The same can also be done when you're defining the type from a union type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05i9ljo6fn5pjmczag9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05i9ljo6fn5pjmczag9j.png" alt="Cast to precise from union type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  You're infering a type from an external input
&lt;/h2&gt;

&lt;p&gt;It can be that a type comes from an external input and you have no idea what type it is. In that case, it's a mix between both previous reason.&lt;/p&gt;

&lt;p&gt;As an example, it could be a DOM API like the following where you specify the precise type in a generic syntax&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// here TS won't know what element you're accessing. So it will by default use HTMLElement | null&lt;/span&gt;
&lt;span class="c1"&gt;// But we can cast it to what we know it is with the angle-bracket syntax &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aFieldInTheHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username-field&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;h1&gt;
  
  
  Best practices when doing a cast
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Always Guard
&lt;/h2&gt;

&lt;p&gt;One thing to not forget is that the cast is only existing in typescript. Once compiled, it's javascript and there's no mention of the type anymore. For that reason, casting is not enough and you have to first check explicitly (= Guard) the value to ensure it is what you think it is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05i9ljo6fn5pjmczag9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05i9ljo6fn5pjmczag9j.png" alt="Example of guards before cast"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Type predicates and guard functions
&lt;/h2&gt;

&lt;p&gt;To help you writing guards and cast in one shot, Typescript developers have created type predicates like the &lt;code&gt;is&lt;/code&gt; keyword below (&lt;a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates" rel="noopener noreferrer"&gt;See official documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;By using them, simply calling this function will cast the variable automatically and correctly from where the guard is called by refering to the returned boolean.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9vqmhnuqf93tcqwpqsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9vqmhnuqf93tcqwpqsa.png" alt="Example of type predicates function"&gt;&lt;/a&gt;&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;possibleFish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;swim&lt;/span&gt;&lt;span class="p"&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swim&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;possibleFish&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// here the variable is infered as a Fish&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;unknown&lt;/code&gt; type to explicitly force cast
&lt;/h2&gt;

&lt;p&gt;In recent release of TS (v. 3+), they've added a new type: unknown. (See &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This type is used to define a type that we don't know what it is, but where we don't want to use &lt;code&gt;any&lt;/code&gt; to not completely "disable" type check.&lt;br&gt;
New TS version will also force to use this type to prevent you to cast completely different object, as doing so would look like a buggy implementation. And if you really have a good reason to do so, then you're adding an additional cast to unknown to make everyone aware it's intended.&lt;/p&gt;

&lt;p&gt;Let's think about a use case where you want to cast an object to another, but you know they've nothing in common. It's not from a union type, it's not from inheritance, it's just completely different, like casting a pizza into a tree: 🍕 ▶ 🌳.&lt;/p&gt;

&lt;p&gt;It's something that should probably never happen, and that's why TS doesn't allow it as easily as before. If you try it, here's how it will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7d4sayddsl5qrzdyg43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7d4sayddsl5qrzdyg43.png" alt="Example of cast of different objects without unknown type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;with the following error&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Conversion of &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'{ price: number; size: number; ingredients: string[]; }'&lt;/span&gt; to &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'Tree'&lt;/span&gt; may be a mistake because neither &lt;span class="nb"&gt;type &lt;/span&gt;sufficiently overlaps with the other. If this was intentional, convert the expression to &lt;span class="s1"&gt;'unknown'&lt;/span&gt; first.
  Type &lt;span class="s1"&gt;'{ price: number; size: number; ingredients: string[]; }'&lt;/span&gt; is missing the following properties from &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'Tree'&lt;/span&gt;: color, height, age&lt;span class="o"&gt;(&lt;/span&gt;2352&lt;span class="o"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Typescript detected that this cast is probably a mistake, and tells it to you. If now for a mysterious reason, you think it's totally ok to cast a 🍕 ▶ 🌳, you can force that cast by casting into unknown first. This will tell the compiler "Trust me, I know it looks wrong, but YOLO!!".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn62z5uys710r4mvxmyq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn62z5uys710r4mvxmyq0.png" alt="Example of a cast with unknown type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Typescript is about typings, but you always have a way to break the typing for good or bad reasons. So here are some key advices.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always type (not cast) all your code but forget the &lt;code&gt;any&lt;/code&gt; as much as possible.&lt;/li&gt;
&lt;li&gt;If you have to cast, it's a polymorphism-like reason, or it's probably a code smell.&lt;/li&gt;
&lt;li&gt;If you want to cast for another reason and you're sure it's justified, then use the &lt;code&gt;unknown&lt;/code&gt; type, and maybe add a comment about the reason for future readers 🙏.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last but not least, don't forget one important rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Typescript is only about types in your IDE/compiler. Once it's running in the browser/engine there's external factors in the game, and nothing will prevent your code to be of the wrong type! =&amp;gt; be defensive.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Tell me in comments 💬 if you see other valid use cases for casts than the one listed above. &lt;br&gt;
Thanks for reading 🤘&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>cast</category>
      <category>type</category>
      <category>polymorphism</category>
    </item>
  </channel>
</rss>
