<?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>Forem: about14sheep</title>
    <description>The latest articles on Forem by about14sheep (@about14sheep).</description>
    <link>https://forem.com/about14sheep</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%2F437580%2Ff33cf53c-bf27-4d9b-a9cb-38177bd7e9f8.jpeg</url>
      <title>Forem: about14sheep</title>
      <link>https://forem.com/about14sheep</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/about14sheep"/>
    <language>en</language>
    <item>
      <title>Understanding the Monotonic Stack To UP Your Data Structure Game</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Mon, 08 Jan 2024 23:50:36 +0000</pubDate>
      <link>https://forem.com/about14sheep/understanding-the-monotonic-stack-to-up-your-data-structure-game-4llh</link>
      <guid>https://forem.com/about14sheep/understanding-the-monotonic-stack-to-up-your-data-structure-game-4llh</guid>
      <description>&lt;p&gt;The Monotonic Stack be very difficult to understand, and even hard to actually utilize!&lt;/p&gt;

&lt;p&gt;I wrote up a solution over on leetcode that solves the problem &lt;a href="https://leetcode.com/problems/final-prices-with-a-special-discount-in-a-shop/description/"&gt;1475. Final Prices With a Special Discount in a Shop&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am testing out using DEV to get feedback on solutions I write up (over on leetcode), so please check it out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/final-prices-with-a-special-discount-in-a-shop/solutions/4531465/simple-non-increasing-monotonic-stack-detailed-solution/"&gt;Monotonic Stack Solution and Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this helps feel free to let me know either here or there! If you have any suggestions, or see things I can make more clear, don't hesitate to let me know!&lt;/p&gt;

</description>
      <category>dsa</category>
      <category>tutorial</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>ESLint Understand By Doing Part 1: Abstract Syntax Trees</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Thu, 30 Mar 2023 02:39:34 +0000</pubDate>
      <link>https://forem.com/about14sheep/eslint-understand-by-doing-part-1-abstract-syntax-trees-2dj0</link>
      <guid>https://forem.com/about14sheep/eslint-understand-by-doing-part-1-abstract-syntax-trees-2dj0</guid>
      <description>&lt;p&gt;Like everything in software development, its best to learn by doing. In this blog series we will go over what is happening, under the hood, when you lint your JavaScript files by writing our very own custom eslint rule!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the stage
&lt;/h2&gt;

&lt;p&gt;Like many I am always searching for answers to life's greatest questions. Also like many, I can narrow these questions down to the three most elusive:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What happens when we die?&lt;/li&gt;
&lt;li&gt;Do aliens exist?&lt;/li&gt;
&lt;li&gt;How does ESLint work?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Due to recent advances in modern sciences we can finally begin to understand the most important of these questions: How does ESLint &lt;em&gt;work&lt;/em&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  TL:DR
&lt;/h2&gt;

&lt;p&gt;I have no idea what I am talking about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstract Syntax Trees
&lt;/h2&gt;

&lt;p&gt;When you run ESLint, the first thing it does is create an Abstract Syntax Tree (AST) of your code. Basically an AST is a description of your codes syntax. A tool can use this description to evaluate your codes structure.&lt;/p&gt;

&lt;p&gt;ESLint is not the only tool that uses ASTs. The TypeScript parser creates an AST in its own format to check for incomplete code, type checking, and if you have used the &lt;code&gt;any&lt;/code&gt; type implicitly (hehe).&lt;/p&gt;

&lt;p&gt;For this blog we will focus on how ESLint uses an AST to understand your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn by doing
&lt;/h2&gt;

&lt;p&gt;The best way to understand what an AST is.. is to simply play with them over on &lt;a href="https://astexplorer.net/"&gt;AST Explorer&lt;/a&gt;. I like to switch the right side panel to &lt;code&gt;json&lt;/code&gt; as I find it easier to follow, but you do you.&lt;/p&gt;

&lt;p&gt;You can follow along with this example:&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="c1"&gt;// Simply setting a variable `foo` to a string 'bar'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&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;ESLint's AST format, &lt;a href="https://github.com/ESTree/ESTree"&gt;ESTree&lt;/a&gt;, would represent this line of code as:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Program"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"body"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VariableDeclaration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"declarations"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VariableDeclarator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Identifier"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"foo"&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;"init"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Identifier"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bar"&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="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;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"const"&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&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;You can gather a lot of information from this. To help we can break it down, then build it back up while we describe whats going on.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Root
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Program"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"body"&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;important&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;now&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;"sourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&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;The root of this object has a &lt;code&gt;type&lt;/code&gt; of 'Program'. This is standard and encapsulates the the rest of the &lt;em&gt;program&lt;/em&gt; code. It shows what byte the program code starts and ends, in the file, as well as describes the type of structure your file has, like whether it is a commonJS file or a ES module file.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Body
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Program"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"body"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VariableDeclaration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"declarations"&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;important&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;now&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;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"const"&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&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;In the &lt;code&gt;body&lt;/code&gt; of the program you have an array of objects. This is where everything you write lives. Since we are only declaring a variable in our program, there is only one object whos type is of &lt;code&gt;"VariableDeclaration"&lt;/code&gt;. If we were to add a function to the file, a new object would pop up in the &lt;code&gt;body&lt;/code&gt; array (specifically it would be a &lt;code&gt;"FunctionDeclaration"&lt;/code&gt; object).&lt;/p&gt;

&lt;p&gt;Looking back at the &lt;code&gt;"VariableDeclaration"&lt;/code&gt; object you will notice it has the familiar &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;, as well the &lt;code&gt;kind&lt;/code&gt; of variable it is (its a constant).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Meat
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Program"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"body"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VariableDeclaration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"declarations"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VariableDeclarator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Identifier"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"foo"&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;"init"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Identifier"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bar"&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="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;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"const"&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="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&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;Now to bring it all back by adding the meat, the &lt;code&gt;"declarations"&lt;/code&gt; property. Inside of this property is where the meat is. The &lt;code&gt;id&lt;/code&gt; object is where the &lt;em&gt;name&lt;/em&gt; of our variable is housed. Likewise, the &lt;code&gt;init&lt;/code&gt; property is where the &lt;em&gt;value&lt;/em&gt; our variable was initialized too is house. Each of these nested objects also has a &lt;code&gt;type&lt;/code&gt; property and their own &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; properties. Can you see a pattern?&lt;/p&gt;

&lt;p&gt;That's all an AST is. It simply describes what and where the individual pieces of your code are. This is the map ESLint uses to run its rules off of.&lt;/p&gt;

&lt;p&gt;In part 2 of this series we will show how ESLint does this by creating rules of our own.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>productivity</category>
      <category>testing</category>
    </item>
    <item>
      <title>Type Assertions, Trucks, and Aliens</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Sun, 04 Dec 2022 14:46:23 +0000</pubDate>
      <link>https://forem.com/about14sheep/type-assertions-trucks-and-aliens-be2</link>
      <guid>https://forem.com/about14sheep/type-assertions-trucks-and-aliens-be2</guid>
      <description>&lt;p&gt;Buckle up, yo.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm listening to R&amp;amp;B right now
&lt;/h2&gt;

&lt;p&gt;It's extremely early where I am, and I couldn't sleep. So like any logical person would be doing, I was reading through the &lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;TypeScript Handbook&lt;/a&gt;. As I am reading the part about &lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;type assertions&lt;/a&gt; (the &lt;code&gt;as&lt;/code&gt; keyword); I couldn't help but think back to a &lt;a href="https://stackoverflow.com/questions/71190622/multiple-type-assertions-in-typescript/71190990#71190990"&gt;StackOverflow answer&lt;/a&gt; I wrote about &lt;em&gt;multiple&lt;/em&gt; type assertions. Don't get me wrong, I like my answer. However, it's just that its... well its...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eQ94y51b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/373ksydywucq1g4d450p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eQ94y51b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/373ksydywucq1g4d450p.jpg" alt="Even more boring than this dude" width="438" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While laying there I had an epiphany, the likes of which would make every Ancient Astronaut Theorist proud. I could spice up the explanation of type assertions (and make it more understandable) if I added &lt;strong&gt;aliens&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What even is TypeScript?
&lt;/h2&gt;

&lt;p&gt;If you don't know what TypeScript is, you should. That's all I have to say about that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Assertions
&lt;/h2&gt;

&lt;p&gt;Now that it's just the TS nerds; lets talk about Type Assertions. In short (because obviously I am going to explain it WAY cooler further down), a type assertion is you telling the compiler whats up. The compiler isn't the great &lt;a href="https://en.wikipedia.org/wiki/Giorgio_A._Tsoukalos"&gt;Giorgio A. Tsoukalos&lt;/a&gt;, sometimes &lt;em&gt;you&lt;/em&gt; just know better. Type Assertions allow you to tell the compiler that a particular type will &lt;em&gt;behave&lt;/em&gt; like another (i.e. have the same shape). I won't bog us down with code yet, and the handbook has a &lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions"&gt;great example&lt;/a&gt; so i'll just steal that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example, if you’re using &lt;code&gt;document.getElementById&lt;/code&gt;, TypeScript only knows that this will return some kind of &lt;code&gt;HTMLElement&lt;/code&gt;, but you might know that your page will always have an &lt;code&gt;HTMLCanvasElement&lt;/code&gt; with a given ID.&lt;/p&gt;

&lt;p&gt;In this situation, you can use a type assertion to specify a more specific type:&lt;/p&gt;


&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myCanvas&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="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main_canvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLCanvasElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;That's all well and good, pretty easy to understand. However, there are obvious limitations to this. What if I tried to tell the stoopid computer machine this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error, sending nuclear launch codes to Russia!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript will throw a fit, and its correct to do so. The compiler is smart enough to know there is no possible way this number &lt;code&gt;42&lt;/code&gt; can behave like a string. Instead of me grinding this down, you go try it in plain old JavaScript. Try and read the &lt;code&gt;.length&lt;/code&gt; property of &lt;code&gt;42&lt;/code&gt; and see if you don't cause World War 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿¿¿Where Aliens???
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FC3pCDwN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91r1qp6gysehtfryq3qg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FC3pCDwN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91r1qp6gysehtfryq3qg.jpg" alt="where banana but its aliens" width="780" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the compiler is so smart, why does asserting &lt;code&gt;42&lt;/code&gt; to the type &lt;code&gt;any&lt;/code&gt; (or &lt;code&gt;unknown&lt;/code&gt;) allow me to then assert it as a string??? Am I bamboozling the compiler???&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;myVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can I now magically call the &lt;code&gt;.length&lt;/code&gt; property of &lt;code&gt;42&lt;/code&gt; and &lt;em&gt;not&lt;/em&gt; cause World War 3?&lt;/p&gt;

&lt;p&gt;Slow down on the questions, it's early and the coffee is still brewing.&lt;/p&gt;

&lt;p&gt;The answer to &lt;code&gt;42.length&lt;/code&gt; is still no. That will NEVER be a thing. Give it up already, kid.&lt;/p&gt;

&lt;p&gt;However, you &lt;em&gt;are&lt;/em&gt; bamboozling the compiler. When you cast the multiple type assertion spell, it makes the compiler immediately believe you (there is not even a saving roll). It throws its little compiler hands up and says "ok dungeon master, you know best" and goes about its day.&lt;/p&gt;

&lt;p&gt;Why you ask, again? That's where the aliens come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  No more memes, just &lt;em&gt;facts&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Now that it's &lt;em&gt;really&lt;/em&gt; just the TS nerds; let's start with two data types, one is a truck:&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;interface&lt;/span&gt; &lt;span class="nx"&gt;Truck&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;numDoors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;drive&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// truck method to drive, cause all trucks drive&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the other is a plane:&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;interface&lt;/span&gt; &lt;span class="nx"&gt;Plane&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;numPropellers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;fly&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// plane method to fly, cause all planes fly&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets just focus on the truck for now. If I were to show you this truck (&lt;code&gt;const truck: Truck&lt;/code&gt;) you would be able to assume it does truck things. You would expect a number of doors to access it, its color, and other truck things. If I told you to go and drive the truck (&lt;code&gt;truck.drive()&lt;/code&gt;) you would see no problem thinking you could hop in and drive it.&lt;/p&gt;

&lt;p&gt;What if I told you to fly (&lt;code&gt;truck.fly()&lt;/code&gt;) the truck? You would throw a syntax error and remind me that it is physically impossible for trucks to fly; that's what planes do.&lt;/p&gt;

&lt;p&gt;Even if I said, think of this truck &lt;em&gt;as&lt;/em&gt; a plane:&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;truck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Truck&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;insert&lt;/span&gt; &lt;span class="nx"&gt;truck&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Plane&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would probably slap me and leave the room. You can not be fooled so easily, you are a &lt;em&gt;smart&lt;/em&gt; compiler!&lt;/p&gt;

&lt;p&gt;Now what if I told you it was an &lt;strong&gt;alien&lt;/strong&gt; truck?&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;truck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Truck&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;insert&lt;/span&gt; &lt;span class="nx"&gt;truck&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well now it could be anything (the &lt;code&gt;any&lt;/code&gt; type you might say?). You have no idea what them aliens be doing these days. It is perfectly plausible that an &lt;em&gt;alien&lt;/em&gt; truck can fly!&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;truck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Truck&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;insert&lt;/span&gt; &lt;span class="nx"&gt;truck&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Plane&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would have no problem getting in the truck and attempting to make it fly. You do so &lt;code&gt;truck.fly()&lt;/code&gt;, and the truck &lt;em&gt;explodes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's what multiple Type Assertions are doing (and the dangers!). By broadening the type to &lt;code&gt;any&lt;/code&gt; anything is possible. So its then perfectly valid (syntactically) to narrow an &lt;code&gt;any&lt;/code&gt; type down to a &lt;code&gt;string&lt;/code&gt; in our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  BUT WHAT ABOUT &lt;code&gt;42.length&lt;/code&gt;??
&lt;/h2&gt;

&lt;p&gt;You would be correct in worrying about this. Since the compiler does not care, you could run this code. In code the "alien" veil will come off revealing a regular old truck trying to fly, when it can't. Then the program crashes just as the truck would.&lt;/p&gt;

&lt;p&gt;However, there is a correct way to do this. Instead of going to aliens for a flying truck, you could just invent it like the genius you are!&lt;/p&gt;

&lt;p&gt;In TypeScript you can extend interfaces to add functionality to them, so to make your special truck you would simply:&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;interface&lt;/span&gt; &lt;span class="nx"&gt;FlyingTruck&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Truck&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// You will get all the properties of the Truck type&lt;/span&gt;
  &lt;span class="nl"&gt;fly&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="k"&gt;void&lt;/span&gt; &lt;span class="c1"&gt;// Plus the ability to fly!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Presto! You have now invented the flying truck. When you then instantiate a &lt;code&gt;FlyingTruck&lt;/code&gt; object you will be able to fly that bad boy without any issue. The compiler is happy, the JavaScript interpreter is happy, Giorgio A. Tsoukalos is happy, and you know what? I'm happy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Felt clever, might delete later
&lt;/h2&gt;

&lt;p&gt;If you liked this article (or just love TypeScript as much as I do) let's talk about it! In the comments, though, to drive engagement on the post ;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jzsa2rkR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0khvw7t56ouyfmfphm9o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jzsa2rkR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0khvw7t56ouyfmfphm9o.gif" alt="lol this one moves" width="498" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Make your own Online Identity Mapping site</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Sat, 16 Apr 2022 00:00:06 +0000</pubDate>
      <link>https://forem.com/about14sheep/make-your-own-online-identity-mapping-site-4b5c</link>
      <guid>https://forem.com/about14sheep/make-your-own-online-identity-mapping-site-4b5c</guid>
      <description>&lt;h2&gt;
  
  
  Online Identity Mapping
&lt;/h2&gt;

&lt;p&gt;Making a developer website for yourself takes a certain type of person. I am one of those that hate it, but I like the idea of having a centralized place for all my links. So, I made an Online Identity Mapping!&lt;/p&gt;

&lt;p&gt;This simple website does exactly what it says on the tin, it takes all the profiles (or at least the ones I want to share) and links them to my name visually. I can then send one link, and know they have everything they need to sleuth.&lt;/p&gt;

&lt;p&gt;You can check mine out &lt;a href="https://austinburger.dev"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make an Online Identity Mapping
&lt;/h2&gt;

&lt;p&gt;I have kept everything very simple. Most of the magic comes from &lt;code&gt;main.css&lt;/code&gt;. It is in "card" style on large screens then moves to vertical on smaller ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting it up
&lt;/h3&gt;

&lt;p&gt;To start, simply &lt;a href="https://github.com/about14sheep/about14sheep.github.io"&gt;fork or clone this repo&lt;/a&gt; onto your machine. From there you can rename it whatever you want by running this in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// replace &amp;lt;whatever&amp;gt; with what you want to call it.
mv about14sheep.github.io &amp;lt;whatever&amp;gt;
// example - rename this project to myproject
mv about14sheep.github.io myproject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can go into your new project to do the rest with &lt;code&gt;cd myproject&lt;/code&gt; replacing &lt;code&gt;myproject&lt;/code&gt; with whatever you choose to name it.&lt;/p&gt;

&lt;p&gt;Now, you don't want all my git history so you can remove it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm -r .git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will also want to remove my CNAME file, or updating it if you have your own domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm CNAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you have a clean slate, lets get &lt;code&gt;git&lt;/code&gt; back (you will need it later):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding your details
&lt;/h3&gt;

&lt;p&gt;To keep it simple, I have added a template html file. This file is an exact copy of the &lt;code&gt;index.html&lt;/code&gt; file, but has spaces for you to insert your details. What you are looking for is big &lt;code&gt;{ PUT YOUR _____ HERE }&lt;/code&gt; where &lt;code&gt;_____&lt;/code&gt; is a title or image path etc.. Don't forget to also remove the brackets &lt;code&gt;{ }&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;If you get stuck, you can peep into &lt;code&gt;index.html&lt;/code&gt; to compare!&lt;/p&gt;

&lt;p&gt;Once you have added all of your information delete my &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then rename the template file to &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mv template.html index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an example, to change the websites title you would look for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" href="./main.css"&amp;gt;
    &amp;lt;title&amp;gt;{PUT YOUR TITLE HERE}&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you wanted to change this to 'John Smith | Terminator' it would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" href="./main.css"&amp;gt;
    &amp;lt;title&amp;gt;John Smith | Terminator&amp;lt;/title&amp;gt; // remove the {brackets}!
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Images and path to images
&lt;/h3&gt;

&lt;p&gt;You can download the image you want for your link, then save them into the &lt;code&gt;images&lt;/code&gt; folder. From there the path becomes &lt;code&gt;./images/your-image.png&lt;/code&gt;. An example being:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="./images/stack-overflow.svg" width="48" height="48"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Changing the pipe color
&lt;/h3&gt;

&lt;p&gt;You can change the pipe accent color directly in the html. If you look for the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element where your name is you will see a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span style="color: gray; border-left: solid; border-color: #F47F24; padding-left: 5px;"&amp;gt;{YOUR ONLINE HANDLE HERE}&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;border-color&lt;/code&gt; to whatever you like&lt;/p&gt;

&lt;h3&gt;
  
  
  Make it yours
&lt;/h3&gt;

&lt;p&gt;This is a simple html file with not a lot going on. Have fun with it, or keep it the way it is. Its up to you! If you do, come back and leave a link in the comments so I can see too!&lt;/p&gt;

&lt;h3&gt;
  
  
  Hosting your Online Identity Mapping
&lt;/h3&gt;

&lt;p&gt;To host this site in all its glory I went the easy route. I turned it into a &lt;a href="https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site#creating-your-site"&gt;github pages site&lt;/a&gt;. This will be pretty simple from where you're at now and that link should explain everything else.&lt;/p&gt;

&lt;p&gt;If you run into any issue let me know here and we can figure it out!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>github</category>
      <category>webdev</category>
    </item>
    <item>
      <title>For Recursion: See learnrecursion.com!</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Sun, 13 Feb 2022 22:22:32 +0000</pubDate>
      <link>https://forem.com/about14sheep/for-recursion-see-learnrecursioncom-5d4g</link>
      <guid>https://forem.com/about14sheep/for-recursion-see-learnrecursioncom-5d4g</guid>
      <description>&lt;p&gt;What are you waiting for?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.learnrecursion.com/"&gt;learnrecursion.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>computerscience</category>
      <category>jokes</category>
    </item>
    <item>
      <title>Firing on all cylinders (Part 2): Understanding Hidden Classes to optimize your JavaScript code</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Mon, 17 Jan 2022 19:40:56 +0000</pubDate>
      <link>https://forem.com/about14sheep/firing-on-all-cylinders-part-2-understanding-hidden-classes-to-optimize-your-javascript-code-5di3</link>
      <guid>https://forem.com/about14sheep/firing-on-all-cylinders-part-2-understanding-hidden-classes-to-optimize-your-javascript-code-5di3</guid>
      <description>&lt;p&gt;In the first part of this series we went over the differences between dynamic and non-dynamic languages. We also went over the difference between how the two approach object storage lookup. We discussed the meaning of offset, the displacement integer in memory between an object and its properties. We then looked into how JavaScript interpreters combine all of that through the use of hash tables.&lt;/p&gt;

&lt;p&gt;We left on a cliff hanger. Realizing that the use of hash tables is inefficient, we hinted at the way v8 mitigates this: Hidden Classes.&lt;/p&gt;

&lt;p&gt;In part 2 of this series we learn what hidden classes are, how they work, and how the v8 JavaScript interpreter handles object storage look up efficiently.&lt;/p&gt;

&lt;p&gt;Along the way I will stop at where, I think, the best understanding of the one-liners (mentioned in part 1) can come from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;Although the concepts mentioned here may not be required to get value from this post. If you are confused with the term offset, how hash tables work, or how JavaScript interpreters handle object storage lookup; I encourage you to go back and read part 1 of this series.&lt;/p&gt;

&lt;p&gt;I have always felt that in order to understand a solution you must first understand the problem the solution solves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rise of Hidden Classes
&lt;/h2&gt;

&lt;p&gt;Hidden Classes are based on the same principles behind the fixed offset mapping in non-dynamic languages (see part 1). The difference is that they are created at runtime, but the outcome is the same. Hidden Classes allow the v8 interpreter to optimize property access time on objects. Hidden Classes are created for each and every object in your program.&lt;/p&gt;

&lt;p&gt;We will go back to our example from part one of the series, the employee constructor function:&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="c1"&gt;// Define a simple constructor function for an employee&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;position&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;When the v8 interpreter reads this code, it first creates a pointer to a location in memory where the call signature for the &lt;code&gt;employee&lt;/code&gt; function is (this 'shell' does not include the properties as we learned in part 1). So you end up with your first hidden class (we can call this HC0):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kBD5wYVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wunqui77w4758je07vr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kBD5wYVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wunqui77w4758je07vr.png" alt="Hidden Class 0" width="166" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, when the interpreter reads the next line (&lt;code&gt;this.salary&lt;/code&gt;) it creates a new hidden class for &lt;code&gt;employee&lt;/code&gt; that includes the offset value for the property &lt;code&gt;this.salary&lt;/code&gt;. It then updates the pointer to now point to this new hidden class. Also, it adds a transition from the first hidden class (HC0) to the new hidden class (HC1):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4jENzAEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zsgam7rdhx35ohonlml0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4jENzAEy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zsgam7rdhx35ohonlml0.png" alt="Hidden Class 1" width="166" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nest, just like previously, when the interpreter reads the next line (&lt;code&gt;this.position&lt;/code&gt;) it creates a new hidden class (and updates the pointer) for &lt;code&gt;employee&lt;/code&gt; that includes the offset value for the property &lt;code&gt;this.position&lt;/code&gt; &lt;em&gt;along with&lt;/em&gt; the already added offset value for the property &lt;code&gt;this.salary&lt;/code&gt;. It then, also just like previously, adds a new transition from (HC1) to (HC2):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VxRj2eLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a839o7pof8c822esqldb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VxRj2eLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a839o7pof8c822esqldb.png" alt="Hidden Class 2" width="166" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of these together in one big happy Harry Potter family tree looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qjMnLHol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hntn48tgr6byc9lx66a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qjMnLHol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hntn48tgr6byc9lx66a.png" alt="Hidden Class All" width="736" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this image you can see the final state of the hidden classes and transitions that make up the &lt;code&gt;employee&lt;/code&gt; constructor function.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it all means
&lt;/h2&gt;

&lt;p&gt;The transitions between the hidden classes are important. They allow for hidden classes to be shared among similar objects. What this means is that if two objects share a hidden class and you add a new property to both of them, transitions ensure that both of the objects will have the same hidden class.&lt;/p&gt;

&lt;p&gt;This is important because being able to share hidden classes between object is what removes that need to have a hash map with each instance. Instead you have one hidden class, accessed by one quick lookup, shared among all objects of the &lt;code&gt;employee&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Now here's the catch...&lt;/p&gt;

&lt;p&gt;The order in which you add dynamic properties to an object matters. Changing this order between two similar objects creates two different hidden classes, omitting the optimization we just discussed!&lt;/p&gt;

&lt;h2&gt;
  
  
  More on the catch
&lt;/h2&gt;

&lt;p&gt;Let's look at what we just discussed in code. We will create two &lt;code&gt;employee&lt;/code&gt; objects and dynamically add some properties to both of them, but we will do it out of order:&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="c1"&gt;// Instantiate the two employees&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;salesEmployee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sales&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ceoEmployee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ceo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// add two new properties to salesEmployee&lt;/span&gt;
&lt;span class="nx"&gt;salesEmployee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Saturday&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;salesEmployee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8675309&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// add the same two properties to ceoEmployee but in a different order&lt;/span&gt;
&lt;span class="nx"&gt;ceoEmployee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9087654&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ceoEmployee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Monday&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks the same, after this is ran you have two employee's with the same structure, all conforming to the &lt;code&gt;employee&lt;/code&gt; constructor function shape. Since the shape of the objects seems identical it seems logical to assume they will share the same hidden class and all the optimization that comes with it... right?&lt;/p&gt;

&lt;p&gt;Nope, as it turns out the v8 interpreter will create two separate hidden classes. One for each, as the offset for the two dynamically added properties will be different. To better explain this i'll use a food analogy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same, Same; but Different
&lt;/h2&gt;

&lt;p&gt;Imagine you are cooking a roast. There are many possible ways to cook a roast, however we will limit this discussion to just two. You might use a crock-pot and let it simmer all day pulling it out at the end to flash sear the edges. You might first sear the edges before you leave it to simmer. In both of these scenarios the ingredients are the same, however the technique is different. Both of them result in a delicious dinner, but both of them has their own distinct &lt;em&gt;recipe&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is how optimizing hidden classes works in v8. The order in which you dynamically add properties to an object matters. Either way, it is valid JavaScript just like both are valid roasts. Also just like the roasts; although the outcome is the same, the &lt;em&gt;recipe&lt;/em&gt; is different. You have to memorize the two different techniques in cooking, so too does the v8 interpreter have to store (memorize) the two different objects and the offset of their property values.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;When you use TypeScript, you are required to do this. The TypeScript compiler will throw an error if you try and add a property to an object dynamically. This is one of the many reasons &lt;strong&gt;we love TypeScript&lt;/strong&gt;. You could almost say that the TL;DR for this post is "use TypeScript".&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;With a better understanding of hidden classes and the catch with how you apply properties dynamically, I think this one-liner might make more sense:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;always add dynamic properties to an instantiation of a class (object) in the same order&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had originally thought to add inline caching to this part of the series, however this post is already a long one. No worries though, we can just do a part 3! &lt;/p&gt;

&lt;p&gt;Thank you for reading and if you have any questions don't hesitate to leave a comment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://engineering.linecorp.com/en/blog/v8-hidden-class/"&gt;Blog: Hidden Classes in v8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://richardartoul.github.io/jekyll/update/2015/04/26/hidden-classes.html"&gt;Another Blog on Hidden Classes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://v8.dev/blog"&gt;The official v8 engine blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Offset_%28computer_science%29"&gt;Wikipedia article on Offset&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Firing on all cylinders(Part 1): Understanding object value lookup in JavaScript interpreters and the rise of hidden classes</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Sun, 16 Jan 2022 23:23:07 +0000</pubDate>
      <link>https://forem.com/about14sheep/firing-on-all-cylinderspart-1-understanding-object-value-lookup-in-dynamic-languages-and-the-rise-of-hidden-classes-in-v8-5h62</link>
      <guid>https://forem.com/about14sheep/firing-on-all-cylinderspart-1-understanding-object-value-lookup-in-dynamic-languages-and-the-rise-of-hidden-classes-in-v8-5h62</guid>
      <description>&lt;p&gt;There is a lot of information around writing performant JavaScript and optimizing your code for the v8 engine. When you are reading through this information you will see a lot of phrases like &lt;em&gt;inline caching&lt;/em&gt;, &lt;em&gt;hidden classes&lt;/em&gt;, and &lt;em&gt;memory offset&lt;/em&gt;; but what does it all mean? You'll come across quick one-liners about "always add properties to a particular instantiation of a class in the same order" or, better yet, "assign all of the objects properties in the constructor". You try to dive into the documentation only to see branching charts with a million tiny words in it that look more like Harry Potter's family tree. At the end of all this, you end up just trying to commit those one liners to memory without fully understanding &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In this series, I am going to attempt to explain these concepts in a way where we don't need pages of flow charts, and with approachable examples (not just look at this code).&lt;/p&gt;

&lt;h2&gt;
  
  
  What to expect
&lt;/h2&gt;

&lt;p&gt;We will start by going over the difference between dynamic and non-dynamic languages (mostly pertaining to how they store objects in memory). Then, in part 2, we will dive into the v8 engine and the methods it uses to efficiently handle the concepts we discuss in part 1. Also, in part 2, I will describe the common pitfalls and ways you can increase the performance of your code. However, you can't make the code better without first understanding the &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;Although I am going to try and explain these concepts in an approachable way, these are not easy concepts to grasp. Most developers can go their entire career without digging into the minute details of how a particular JavaScript engine accesses objects in memory. &lt;/p&gt;

&lt;p&gt;Modern JavaScript Interpreters, like v8, are amazing tech and mostly handle all of this for you. Furthermore, with TypeScript, you have a compiler that can help keep you from making a lot of the common mistakes that can lead to a decrease in performance. However, taking the time to try and understand what is happening under the hood can go a long way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dynamic language
&lt;/h2&gt;

&lt;p&gt;JavaScript is a &lt;em&gt;dynamic&lt;/em&gt; programming language. This means that you can add, remove, and change (the type) property values of objects &lt;em&gt;after&lt;/em&gt; they are initialized. Let's look at the following code:&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="c1"&gt;// Define a simple constructor function for an employee&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Instantiate a new employee&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newHire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sales&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Dynamically add the employee's desired pay day&lt;/span&gt;
&lt;span class="nx"&gt;newHire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Saturday&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;After the employee object is created, their preferred &lt;code&gt;payDay&lt;/code&gt; is added &lt;em&gt;dynamically&lt;/em&gt;. This is all perfectly valid JavaScript. It will run just fine and the newly hired employee will get paid every Saturday.&lt;/p&gt;

&lt;p&gt;The difference between a non-dynamic programming language (meaning all of an objects properties are fixed before compilation) is that new properties &lt;strong&gt;cannot&lt;/strong&gt; be added or removed at runtime. The benefit to a language being non-dynamic is that the values of these properties (or pointers) can be stored in memory with a fixed offset (an integer indicating the displacement between the beginning of an object in memory and any given property). This offset can be easily determined based on the properties type.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Skrrtttt... offset?!?! &lt;strong&gt;displacement&lt;/strong&gt;?!?! You said this would be easy to follow and approachable!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're right, this is why I decided to do this blog in two parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory storage displacement (offset)
&lt;/h2&gt;

&lt;p&gt;The easiest way to explain this is with a simple data structure like an array:&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;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We know we can access a value in that array using its index:&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="nx"&gt;array&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="c1"&gt;// this will get us the item at index 2 ('value3')&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the first value (&lt;code&gt;'value1'&lt;/code&gt;) is at memory position 0, moving two places to the right will give you (&lt;code&gt;'value3'&lt;/code&gt;). So &lt;code&gt;'value3'&lt;/code&gt; has an offset of 2 from the &lt;em&gt;start&lt;/em&gt; of where the array is stored in memory.&lt;/p&gt;

&lt;p&gt;This is simple enough for an array, however not all objects are stored in memory sequentially like an array is. With more complex objects, like the employee function above, you can't be sure where the object, and its properties, will be stored. Thus making it harder to determine the offset between the objects 'shell' (to keep it simple) and its properties. You could have the 'shell' of the object (&lt;code&gt;function employee() {}&lt;/code&gt;) at position 0, then its property &lt;code&gt;this.salary&lt;/code&gt; at position 6 with other objects in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to dynamic vs. non-dynamic
&lt;/h2&gt;

&lt;p&gt;In order to keep up with these offset values, non-dynamic languages (i'll use Java in this case) create a fixed object layout. This layout (or mapping) cannot be changed (as in changing the type), added too, or removed from at runtime. The offset is written in stone, making it easy (usually one instruction) to grab any property value of a given object.&lt;/p&gt;

&lt;p&gt;Since you can add, remove, and even change a properties type in JavaScript at runtime, the interpreter has to allocate a new space in memory and then add a new mapping (offset value) back to the object for every change. It will then have to go back through and clean up the memory by a process called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection"&gt;garbage collection&lt;/a&gt;. In order to keep up with these changes, JavaScript interpreters needed a data structure that can change at runtime. &lt;/p&gt;

&lt;h2&gt;
  
  
  Hash Tables
&lt;/h2&gt;

&lt;p&gt;Instead of using a fixed object layout, like in the non-dynamic Java, most JavaScript interpreters use a dictionary like structure (based on a hash function) to store the objects property values in memory. This is often referred to as a &lt;em&gt;hash table&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;A hash table, simply put, is a collection of key/value pairs. A over-simplified version of what the &lt;code&gt;employee&lt;/code&gt; object might look like in a hash table would be keys mapped to the values of where the &lt;code&gt;employee&lt;/code&gt; object starts in memory, along with the offset value of each of it properties. We can attempt to replicate this using a &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics"&gt;Plain Old JavaScript Object&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;hashTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;employeeInstance1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;memoryStart&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;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;salary_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;position_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;employeeInstance2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;memoryStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;salary_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;position_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="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;If you wanted to add a property to the table (after the value is added in memory), you can simply update that objects 'bucket' in the table.&lt;/p&gt;

&lt;p&gt;Adding &lt;code&gt;payDay&lt;/code&gt; to employee 1 would change the table to this:&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;hashTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;employeeInstance1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;memoryStart&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;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;payDay_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// added property and offset&lt;/span&gt;
          &lt;span class="na"&gt;salary_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;position_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;employeeInstance2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;memoryStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;salary_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;position_offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="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;By doing this, the interpreter is able to add properties to the object anywhere in memory, because it has a dictionary (the hash table) keeping track of where the properties are located and what object they belong too.&lt;/p&gt;

&lt;p&gt;The downside of this is that grabbing the properties value from a hash table is more computationally expensive (more instructions) than the fixed object layout of a non-dynamic language. Instead of having a direct one-to-one mapping of object/property to the offset of where the value is located, the interpreter must search through the hash table for the employee instance, grab the correct property, then use the offset value to &lt;em&gt;finally&lt;/em&gt; get the property's value from memory!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is an extremely over-simplified explanation of how object memory storage hash tables work, but I think it helps in understanding at a very low level (and we are trying to keep this approachable). If you wanted to learn more you can start &lt;a href="https://en.wikipedia.org/wiki/Hash_function"&gt;here&lt;/a&gt; and I have added a very nice blog at the bottom of this post. Just know it is extremely inefficient compared to what is coming next.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Firing on all cylinders
&lt;/h2&gt;

&lt;p&gt;Since using hash tables to get property values is so inefficient, the JavaScript engine NodeJS uses, 'v8', takes a different approach. This approach is built around using Hidden Classes and made faster by Inline Caching.&lt;/p&gt;

&lt;p&gt;OK! Now that the gritty stuff is out of the way. In part 2 of this series we will dive into hidden classes and inline caching. Once you better understand the concepts, it well help you understand those one-line suggestions, mentioned &lt;em&gt;everywhere&lt;/em&gt;, that can make your JavaScript code more performant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://craftinginterpreters.com/hash-tables.html"&gt;Blog: Hash tables&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.programcreek.com/2011/11/what-do-java-objects-look-like-in-memory/"&gt;Blog: How Java stores objects in memory&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://v8.dev/blog"&gt;The official v8 engine blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures"&gt;MDN JavaScript types and data structures&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Offset_%28computer_science%29"&gt;Wikipedia article on Offset&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>Streaming files from AWS S3 using NodeJS Stream API with Typescript</title>
      <dc:creator>about14sheep</dc:creator>
      <pubDate>Sun, 02 Jan 2022 20:35:31 +0000</pubDate>
      <link>https://forem.com/about14sheep/streaming-data-from-aws-s3-using-nodejs-stream-api-and-typescript-3dj0</link>
      <guid>https://forem.com/about14sheep/streaming-data-from-aws-s3-using-nodejs-stream-api-and-typescript-3dj0</guid>
      <description>&lt;h2&gt;
  
  
  Checkout the new npm package!
&lt;/h2&gt;

&lt;p&gt;This simple solution just got easier! I also added some upgrades like the ability to adjusted the size of the range mid stream! Now you can speed up and slow down at will!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/s3-readstream"&gt;https://www.npmjs.com/package/s3-readstream&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use this package as a drop in replacement for &lt;code&gt;AWS.S3.getObject().createReadStream()&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Original Blog
&lt;/h2&gt;

&lt;p&gt;AWS s3 SDK and NodeJS read/write streams makes it easy to download files from an AWS bucket. However, what if you wanted to stream the files instead?&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;I am assuming you have used AWS s3 SDK to download files successfully and are now wanting to convert that functionality to a proper stream. As such, I will omit the AWS implementation and instead show a simple example of how, and where, to instantiate this "smart stream" class.&lt;/p&gt;

&lt;p&gt;I am also assuming you have a (basic) understanding of NodeJS and NodeJS read/write streams.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pipe dream
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;I know that pun was bad, but it's the only one in the article so work with me.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The first solution you will probably come across when implementing your stream (and why I decided to write this article) is to simply take the read stream created off your S3 instance and plug that guy where you need it. Boom streaming!&lt;/p&gt;

&lt;p&gt;...not so fast. &lt;/p&gt;

&lt;p&gt;There is a timeout on connections to an AWS s3 instance set to 120000ms (2 minutes). Unless you have very small files, this just won't cut it for streaming. &lt;/p&gt;

&lt;p&gt;One option is to simply raise that timeout, but then how much should you raise it? Since the timeout is for the total time a connection can last; you would have to either make the timeout some ridiculous amount, or guess how long it will take to stream the file and update the timeout accordingly. This is also not taking into account the stream closing due to HTTP(S)'s own timeout reasons as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bite by Byte
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;I'm sorry. It was right there... I had too!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Timeouts are not the only things that can cause you problems, there's latency too. You can't be certain that your stream isn't going to slow to a crawl in the middle of it, and everyone hates waiting for the buffer (if you should so choose to stream video). Although this problem can't be solved outright, you can make it a lot easier on yourself.&lt;/p&gt;

&lt;p&gt;Instead of just connecting a hose and &lt;em&gt;feeding the beast&lt;/em&gt;, you can use a "smart stream" that fetches a range of data in a single request. Grabbing data as you need it can help you avoid latency, while also keeping you away from those nasty timeouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart Streaming
&lt;/h2&gt;

&lt;p&gt;The idea is to create a stream that uses the power of AWS s3 &lt;br&gt;
 ability to grab a range of data with a single request. We can then grab another range of data with a new request and so on. This stream will pause when its buffer is full, only requesting new data on an as needed basis. This allows us to take all the time we need to process the data (or pause the video, in the middle of it, to go to the bathroom). When the process is done (and hands are washed), it picks right back up where it left off and the show goes on.&lt;/p&gt;
&lt;h2&gt;
  
  
  Put your darkest shades on, &lt;em&gt;you're in&lt;/em&gt;!
&lt;/h2&gt;

&lt;p&gt;Instead of making guesses and fighting random bugs, we can make use of the NodeJS Stream API and create our very own custom readable stream.&lt;/p&gt;

&lt;p&gt;We will start by creating the "smart stream" class:&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;Readable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReadableOptions&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;stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;S3&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;aws-sdk&lt;/span&gt;&lt;span class="dl"&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;class&lt;/span&gt; &lt;span class="nx"&gt;SmartStream&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Readable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;_currentCursorPosition&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="c1"&gt;// Holds the current starting position for our range queries&lt;/span&gt;
    &lt;span class="nx"&gt;_s3DataRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Amount of bytes to grab&lt;/span&gt;
    &lt;span class="nl"&gt;_maxContentLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Total number of bites in the file&lt;/span&gt;
    &lt;span class="nl"&gt;_s3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// AWS.S3 instance&lt;/span&gt;
    &lt;span class="nl"&gt;_s3StreamParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GetObjectRequest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Parameters passed into s3.getObject method&lt;/span&gt;

    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GetObjectRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// You can pass any ReadableStream options to the NodeJS Readable super class here&lt;/span&gt;
        &lt;span class="c1"&gt;// For this example we wont use this, however I left it in to be more robust&lt;/span&gt;
        &lt;span class="nx"&gt;nodeReadableStreamOptions&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ReadableOptions&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nodeReadableStreamOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_maxContentLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3StreamParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;_read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_currentCursorPosition&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_maxContentLength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// If the current position is greater than the amount of bytes in the file&lt;/span&gt;
            &lt;span class="c1"&gt;// We push null into the buffer, NodeJS ReadableStream will see this as the end of file (EOF) and emit the 'end' event&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Calculate the range of bytes we want to grab&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_currentCursorPosition&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3DataRange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// If the range is greater than the total number of bytes in the file&lt;/span&gt;
            &lt;span class="c1"&gt;// We adjust the range to grab the remaining bytes of data&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adjustedRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_maxContentLength&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_maxContentLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// Set the Range property on our s3 stream parameters&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3StreamParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`bytes=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_currentCursorPosition&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;adjustedRange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// Update the current range beginning for the next go &lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_currentCursorPosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;adjustedRange&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="c1"&gt;// Grab the range of bytes from the file&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_s3StreamParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// If we encounter an error grabbing the bytes&lt;/span&gt;
                    &lt;span class="c1"&gt;// We destroy the stream, NodeJS ReadableStream will emit the 'error' event&lt;/span&gt;
                    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// We push the data into the stream buffer&lt;/span&gt;
                    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="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;
  
  
  Let's break this down a bit
&lt;/h2&gt;

&lt;p&gt;We are extending the Readable class from the NodeJS Stream API to add some functionality needed to implement our "smart stream". I have placed underscores (_) before some of the properties to separate our custom implementation from functionality we get, right out of the box, from the Readable super class. &lt;/p&gt;

&lt;p&gt;The Readable class has a buffer that we can push data in too. Once this buffer is full, we stop requesting more data from our AWS s3 instance and instead push the data to another stream (or where ever we want the data to go). When we have room in the buffer, we make another request to grab a range of bites. We repeat this until the entire file is read.&lt;/p&gt;

&lt;p&gt;The beauty of this simple implementation is that you have access to all of the event listeners and functionality you would expect from a NodeJS readStream. You can even pipe this stream into 'gzip' and stream zipped files!&lt;/p&gt;

&lt;p&gt;Now that we have the SmartStream class coded, we are ready to wire it into a program. &lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing with AWS S3
&lt;/h2&gt;

&lt;p&gt;For this next part, as I am assuming you understand the AWS s3 SDK, I am simply going to offer an example of how to establish the stream.&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;SmartStream&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Path&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;SmartStream&lt;/span&gt; &lt;span class="nx"&gt;file&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;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createAWSStream&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SmartStream&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;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucketParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;Key&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;try&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;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resolveS3Instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="c1"&gt;// After getting the data we want from the call to s3.headObject&lt;/span&gt;
                &lt;span class="c1"&gt;// We have everything we need to instantiate our SmartStream class&lt;/span&gt;
                &lt;span class="c1"&gt;// If you want to pass ReadableOptions to the Readable class, you pass the object as the fourth parameter&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SmartStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ContentLength&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check this out in an HD video streaming app on my github!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/about14sheep/awsstreaming/tree/master"&gt;The most simple HD video streaming app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading! If you liked this blog let me know in the comments below!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;This is only one example of the amazing things you can do with the NodeJS standard Stream API. For further reading checkout the &lt;a href="https://nodejs.org/api/stream.html"&gt;NodeJS Stream API docs&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
