<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sam Wight</title>
    <description>The latest articles on DEV Community by Sam Wight (@samwightt).</description>
    <link>https://dev.to/samwightt</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%2F142544%2F93a0859b-0934-45ab-9227-559082c026fb.jpg</url>
      <title>DEV Community: Sam Wight</title>
      <link>https://dev.to/samwightt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samwightt"/>
    <language>en</language>
    <item>
      <title>Today in TypeScript: the keyof operator</title>
      <dc:creator>Sam Wight</dc:creator>
      <pubDate>Thu, 02 Dec 2021 17:26:17 +0000</pubDate>
      <link>https://dev.to/samwightt/today-in-typescript-the-keyof-operator-445b</link>
      <guid>https://dev.to/samwightt/today-in-typescript-the-keyof-operator-445b</guid>
      <description>&lt;p&gt;Sometimes when you're trying to index on an object TypeScript will give you an error like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&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;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;printUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;for&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;key&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// Error! Element implicitly has 'any' type&lt;/span&gt;
    &lt;span class="c1"&gt;// because expression of type 'string' can't be used to index type 'User'.&lt;/span&gt;
    &lt;span class="c1"&gt;// No index signature with a parameter of type 'string' was found on type 'User'.&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;Let's figure out what's going on here. &lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking it down
&lt;/h2&gt;

&lt;p&gt;First, if we break out &lt;code&gt;user[key]&lt;/code&gt; into a variable and hover over the variable, we can see that it has the type &lt;code&gt;any&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KsMaUuLH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/03c2fsfdazxy35z0hwtn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KsMaUuLH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/03c2fsfdazxy35z0hwtn.png" alt="Screenshot showing that TypeScript infers the type of  raw `user[key]` endraw  as  raw `any` endraw " width="880" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is this happening? TypeScript tells us in the error. Let's look at the error again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'User'.
  No index signature with a parameter of type 'string' was found on type 'User'.(7053)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Starting with the first line, TypeScript tells us that &lt;code&gt;user[key]&lt;/code&gt; has the type &lt;code&gt;any&lt;/code&gt;. The reason why it's giving us this error is because &lt;code&gt;noImplicitAny&lt;/code&gt; is turned on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Element implicitly has 'any' type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is this happening? TypeScript tells us that it's because a &lt;code&gt;string&lt;/code&gt; type can't be used to index on type &lt;code&gt;User&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;because expression of type 'string' can't be used to index type 'User'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where's this string type coming from? Well, we're using the variable &lt;code&gt;key&lt;/code&gt; to index on &lt;code&gt;user&lt;/code&gt;, so let's look at its inferred type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zXabKeG9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9s4e1j68aoehdhyecvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zXabKeG9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9s4e1j68aoehdhyecvs.png" alt="Screenshot showing the inferred type of  raw `key` endraw  is  raw `string` endraw ." width="476" height="149"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ah, that makes more sense! TypeScript thinks that &lt;code&gt;key&lt;/code&gt; is of type &lt;code&gt;string&lt;/code&gt;. This comes from the type of &lt;code&gt;keys&lt;/code&gt;, which is &lt;code&gt;string[]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reason why TypeScript doesn't allow us to index on &lt;code&gt;User&lt;/code&gt; with type &lt;code&gt;string&lt;/code&gt; is because it doesn't have an 'index signature':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No index signature with a parameter of type 'string' was found on type 'User'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An &lt;a href="https://dmitripavlutin.com/typescript-index-signatures/"&gt;index signature&lt;/a&gt; is a thing you can add to interfaces when you only know the key and value types of an object. It tells TypeScript to allow you to index on an object with much broader types. For example, 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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UsersTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would tell TypeScript to allow us to index on &lt;code&gt;UsersTable&lt;/code&gt; with anything that is of type &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the important part: if we don't have an index signature, TypeScript will have a stricter default. &lt;strong&gt;TypeScript will only allow us to index on an object if the variable we're using to index is assignable to the &lt;em&gt;union of the keys&lt;/em&gt; of that object&lt;/strong&gt;. So in the case of &lt;code&gt;User&lt;/code&gt;, TypeScript will only allow us to index with a variable assignable to the type &lt;code&gt;"name" | "email" | "password"&lt;/code&gt;. (&lt;a href="https://www.typescriptlang.org/docs/handbook/type-compatibility.html"&gt;You can read on type assignability here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This means that we need &lt;code&gt;key&lt;/code&gt; to have a type of &lt;code&gt;"name" | "email" | "password"&lt;/code&gt;, or something narrower (a subset of that, for example &lt;code&gt;"name"&lt;/code&gt; or &lt;code&gt;"email" | "password"&lt;/code&gt;). How do we fix that?&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing the problem: Solution One
&lt;/h2&gt;

&lt;p&gt;The first way we can fix this is pretty simple. Let's write out the type that TypeScript wants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;UserKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&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;And let's tell it that &lt;code&gt;keys&lt;/code&gt; is an array of &lt;code&gt;UserKey&lt;/code&gt;s:&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;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserKey&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&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;This works! The error goes away and TypeScript is happy.&lt;/p&gt;

&lt;p&gt;To make sure we understand why, let's go back over the inferred types of the variables. &lt;code&gt;keys&lt;/code&gt; is of type &lt;code&gt;Array&amp;lt;UserKey&amp;gt;&lt;/code&gt; (or &lt;code&gt;UserKey[]&lt;/code&gt;), which means &lt;code&gt;key&lt;/code&gt; is now of type &lt;code&gt;UserKey&lt;/code&gt;. &lt;code&gt;UserKey&lt;/code&gt; is shorthand for &lt;code&gt;"name" | "email" | "password"&lt;/code&gt;. Because &lt;code&gt;"name" | "email" | "password"&lt;/code&gt; is assignable to the union of the keys of &lt;code&gt;User&lt;/code&gt;, TypeScript lets us index on it. And now &lt;code&gt;user[key]&lt;/code&gt; doesn't have an &lt;code&gt;any&lt;/code&gt; type and is of type &lt;code&gt;string&lt;/code&gt;. &lt;a href="https://www.typescriptlang.org/play?ssl=10&amp;amp;ssc=1&amp;amp;pln=11&amp;amp;pc=1#code/JYOwLgpgTgZghgYwgAgKoGdrIN4FgBQyyIcAthAFzLphSgDmA3AURKXMADZU10hMtkABzjp0AdwD2UACY9aDZvgC+BAmACeQlBmgBpCBuQBeZACIS5M8gA+5th07W7ZkWKmyza-DACuIBDBgSRBhPjBdKAAKX0woKkiAShxBBBCaZABrQ3QqAEEoKDgNAB5Igw0APhNkAG0LMggzABp7di4W8zcJaRkzAF0lIkEYaWQotJAM7KNJGCyc5LxCImRJjIA3OE5fFFNY6FqZ-sEidclOCAA6Tkl6GLijw37kgHpX5ABRQukAQi-LuRwMhgKQhJxgAhgGBOEYABaiZAAcjgIA0SOQmm0p2Q72QACMIAg4AdkBAAB5CKAQMTBUJzTFaFBI3gMDHEkBIsAElAHGSYyQgkAyCmM7TIyJIq44vEAOUFoBF5OowHoJDAvmpyHE0LhyDgwjgRXIkCgyAZWOZrP4GPEiNG-n5ITFzMl0pWqhUQA"&gt;Here's a TypeScript playground where you can experiment with this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yay, we fixed the error! But there's one small problem: what if we add keys to &lt;code&gt;User&lt;/code&gt;? What happens then? Well we'd have to update the &lt;code&gt;UserKey&lt;/code&gt; union with the new keys we added. There's also the potential to misspell a key or forget to add one, which TypeScript will scream at us for.&lt;/p&gt;

&lt;p&gt;Fortunately, there's a way around this. The &lt;code&gt;keyof&lt;/code&gt; operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution two: The &lt;code&gt;keyof&lt;/code&gt;operator
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/keyof-types.html"&gt;Here's the documentation for the &lt;code&gt;keyof&lt;/code&gt; operator in the TypeScript handbook&lt;/a&gt;. The docs tell us that &lt;code&gt;keyof&lt;/code&gt; does this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;keyof&lt;/code&gt; operator takes an object type and produces a string or numeric literal union of its keys.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So this does exactly the same thing as what TypeScript does under the hood for indexing! &lt;code&gt;keyof&lt;/code&gt; takes an interface / object and returns the union of all of the keys in it. So for our &lt;code&gt;User&lt;/code&gt; interface, it would return &lt;code&gt;"name" | "email" | "password"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can now use this to shorten our &lt;code&gt;UserKey&lt;/code&gt; definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;UserKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works exactly the same as before, but now if we update &lt;code&gt;User&lt;/code&gt;, we don't have to touch &lt;code&gt;UserKey&lt;/code&gt;. Pretty great!&lt;/p&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>How to rename your main Git branch to main</title>
      <dc:creator>Sam Wight</dc:creator>
      <pubDate>Wed, 17 Jun 2020 02:38:17 +0000</pubDate>
      <link>https://dev.to/samwightt/how-to-rename-your-main-git-branch-to-main-3ddk</link>
      <guid>https://dev.to/samwightt/how-to-rename-your-main-git-branch-to-main-3ddk</guid>
      <description>&lt;p&gt;I've been seeing a lot of talk lately about renaming the default GitHub branch to &lt;code&gt;main&lt;/code&gt;. I think this is a really good idea! Something simple that promotes inclusion is &lt;em&gt;always&lt;/em&gt; something that I will support. Thankfully, Git branches are built to make changes like this &lt;em&gt;extremely easy&lt;/em&gt;. In this (very short) post, I'll show you how to rename your main Git branch to &lt;code&gt;main&lt;/code&gt;, and how to update the default branch on GitHub. Overall, this should take you about five minutes total. Just five minutes!&lt;/p&gt;

&lt;h1&gt;
  
  
  The commands
&lt;/h1&gt;

&lt;p&gt;First, here's the commands to change your default branch name to &lt;code&gt;main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-m&lt;/span&gt; old_branch_name main
git push &lt;span class="nt"&gt;--set-upstream&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first command renames &lt;code&gt;old_branch_name&lt;/code&gt; (your default branch name here, whatever that may be) to &lt;code&gt;main&lt;/code&gt;. The next branch pushes that new main branch to the remote. Replace &lt;code&gt;origin&lt;/code&gt; with whatever remote you use for your main repo host. Once you run these commands, you'll have your brand new &lt;code&gt;main&lt;/code&gt; branch. Isn't that cool!&lt;/p&gt;

&lt;h1&gt;
  
  
  Updating GitHub
&lt;/h1&gt;

&lt;p&gt;If you're using GitHub like I am, then updating your default branch is a little bit more involved. First, navigate to &lt;strong&gt;Your Repo&lt;/strong&gt; → &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Branches&lt;/strong&gt;. There, you should be able to change the default branch to &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you don't want to keep the old branch name around, you can easily delete it (after all, it was easy enough to create!). Navigate to the root of your repo and click on the branches icon (the one with the number of branches your repo has). You should then be able to delete your old branch name.&lt;/p&gt;

&lt;p&gt;Congrats, you've now renamed your default branch to &lt;code&gt;main&lt;/code&gt;!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Centering a div with Flexbox</title>
      <dc:creator>Sam Wight</dc:creator>
      <pubDate>Mon, 08 Jun 2020 18:27:15 +0000</pubDate>
      <link>https://dev.to/samwightt/centering-a-div-with-css-fep</link>
      <guid>https://dev.to/samwightt/centering-a-div-with-css-fep</guid>
      <description>&lt;p&gt;I saw the tweet below on my timeline today:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1270049224378507267-467" src="https://platform.twitter.com/embed/Tweet.html?id=1270049224378507267"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1270049224378507267-467');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1270049224378507267&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Here's a simple, no bullshit guide to centering content with CSS using Flexbox. &lt;a href="https://caniuse.com/#feat=flexbox" rel="noopener noreferrer"&gt;Make sure to check the Flexbox CanIUse to make sure your target browsers have good support for it, otherwise this might not work.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating the skeleton
&lt;/h1&gt;

&lt;p&gt;To start, let's write some HTML. &lt;code&gt;parent-div&lt;/code&gt; is the element that will hold the child div that we want to center.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Flexbox CSS Centering Example&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"parent-div"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"child-div"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;This is an example&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're wanting a good place to play around with this code in the browser, I recommend using CodePen. &lt;a href="https://codepen.io/samwightt/pen/gOPaWQx" rel="noopener noreferrer"&gt;Here's the pen with the HTML used for this post.&lt;/a&gt; Just type in the CSS as we go along and you'll see everything updated in real time.&lt;/p&gt;

&lt;p&gt;Our goal will be to get the &lt;code&gt;child-div&lt;/code&gt; post centered within the parent div, both horizontally and vertically. We'll start by adding flexbox to the parent. Before we do this though, let's add some backgrounds to each of these elements so we can see where the browser is rendering them. Ugly, I know.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#parent-div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#child-div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Adding Flexbox to the parent
&lt;/h1&gt;

&lt;p&gt;Making an item display using flex is simple: just use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/display#Inside" rel="noopener noreferrer"&gt;&lt;code&gt;display: flex;&lt;/code&gt;&lt;/a&gt; CSS property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#parent-div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&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 shouldn't notice any changes in how the element is rendering yet. Let's add some height and width to parent element, making it the height and width of the browser viewport:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#parent-div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Centering the content
&lt;/h1&gt;

&lt;p&gt;Now that we have a parent element the width and height of the screen, let's center the child element horizontally and vertically inside the parent div. We'll use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content" rel="noopener noreferrer"&gt;&lt;code&gt;justify-content&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/align-items" rel="noopener noreferrer"&gt;&lt;code&gt;align-items&lt;/code&gt;&lt;/a&gt; CSS properties to make this happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#parent-div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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;And now we should see the child element centered inside the parent div!&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>Thoughts on Glimmer</title>
      <dc:creator>Sam Wight</dc:creator>
      <pubDate>Sat, 15 Feb 2020 05:59:29 +0000</pubDate>
      <link>https://dev.to/samwightt/thoughts-on-glimmer-l2j</link>
      <guid>https://dev.to/samwightt/thoughts-on-glimmer-l2j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was originally published on &lt;a href="https://samw.dev/blog"&gt;my blog&lt;/a&gt;. I have a "Daily Jots" series where I post short, unedited posts every day about random topics. Take a look if you're interested.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve recently gotten into learning &lt;a href="https://emberjs.com/"&gt;Ember.js&lt;/a&gt; for a new project I’m wanting to create (&lt;a href="https://github.com/samwightt/registrar"&gt;my hackathon registration system, Registrar&lt;/a&gt;). While doing so, I came across &lt;a href="https://glimmerjs.com/guides/tracked-properties"&gt;Glimmer&lt;/a&gt;, Ember’s new component engine that’s been extracted from the framework. Glimmer’s been around since 2017 (or a bit earlier), but it was kinda revolutionary for its time: it’s a VM written in JavaScript that efficiently parses bytecode that’s compiled from Handlebars templates. There’s a number of large benefits to this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parsing and compiling JavaScript takes a &lt;strong&gt;significant&lt;/strong&gt; amount of time. There’s a reason why the Chrome team &lt;a href="https://www.youtube.com/watch?v=ff4fgQxPaO0"&gt;recommends that if you’re passing down large amounts of JSON content, you use JSON.parse to process it instead of just including it in your JS&lt;/a&gt;. Browsers can run &lt;code&gt;JSON.parse()&lt;/code&gt; faster than they can process the raw object in JavaScript because JavaScript is a more syntactically complex language. The same goes for things like React apps. It takes a significant amount of time to process and compile the hundreds or thousands of &lt;code&gt;React.createElement()&lt;/code&gt; calls that there might be in a typical React app, which results in a longer &lt;a href="https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint"&gt;First Meaningful Paint&lt;/a&gt;. Glimmer gets rid of this entirely by just reading in a &lt;strong&gt;raw binary&lt;/strong&gt;, which doesn’t have to be parsed at all. Zero parse.&lt;/li&gt;
&lt;li&gt;Glimmer also extracts the strings out of the compiled Handlebars and lets the bytecode reference individual string locations in a root string array. It also &lt;strong&gt;deduplicates&lt;/strong&gt; this array, which means that you’re saving size across your entire app.&lt;/li&gt;
&lt;li&gt;Glimmer is actually set up as two different VMs: an &lt;strong&gt;append&lt;/strong&gt; VM and an &lt;strong&gt;update&lt;/strong&gt; VM. Because Glimmer can see what variables are used where in your Handlebars templates, ti can use &lt;strong&gt;update bytecode&lt;/strong&gt; to efficiently update only the DOM attributes that need updating when a dynamic variable has changed, instead of having to re-render the entire application like in React.
Again, these were conversations going on in &lt;strong&gt;2017&lt;/strong&gt;, kinda before the whole “package size” talk became mainstream with Svelte. Glimmer overall just seems pretty amazing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to learn more about all of this, here’s a few resources I highly recommend checking out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tomdale.net/2017/09/compilers-are-the-new-frameworks/"&gt;Tom Dale’s post on compilers being the new framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=nXCSloXZ-wc"&gt;&lt;strong&gt;Tom Dale’s tech talk on how Glimmer works under the hood&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=l2nD1IxjHUI"&gt;“Glimmer 2, Ember’s new DOM rendering Virtual Machine” by Gavin Joyce&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>ember</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Let's Write: An Auto-Currying Higher Order Function</title>
      <dc:creator>Sam Wight</dc:creator>
      <pubDate>Tue, 25 Jun 2019 13:37:33 +0000</pubDate>
      <link>https://dev.to/samwightt/let-s-write-an-auto-currying-higher-order-function-3b1</link>
      <guid>https://dev.to/samwightt/let-s-write-an-auto-currying-higher-order-function-3b1</guid>
      <description>&lt;p&gt;I've been working on a project lately that involves writing a &lt;strong&gt;lot&lt;/strong&gt; of callback functions, and some of them were getting pretty large. I decided to move as many of them as possible to separate modules to keep things small and relatively simple, but noticed that a lot of them depended on the parent function's scope. Functions in Javascript can't inherit the scope of something that they can't see. The easy way to fix a problem like this would just be to write a function that accepts the scope variables needed and then returns the callback function. This works because the returned callback function will inherit the scope of the parent (the passed variables). So something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;helloCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instanceArg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;instanceArg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callbackArg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callbackArg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Both instance args and callback args are in scope here!&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;default&lt;/span&gt; &lt;span class="nx"&gt;helloCallback&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;would be called like this in a listener in a separate module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;helloCallback&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;./helloCallback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;pretendAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;helloCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's a pretty simple and elegant solution! In the functional programming world, we call something like this &lt;em&gt;currying&lt;/em&gt; (using this very loosely). True currying is where you split all of your function arguments over consecutive functions like Russian dolls. It looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;helloCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;instanceArg1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;instanceArg2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;callbackArg1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;callbackArg2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// all the variables are in scope!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This wasn't really optimal for what I needed though, so I just split my function over two different levels. &lt;/p&gt;

&lt;p&gt;For the hell of it, I decided to write my own function that would automatically curry any function. It would be used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;curried&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;curry&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;three&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;four&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;three&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;four&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and could be called in any of these ways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;curried&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 1 2 3 4&lt;/span&gt;
&lt;span class="nx"&gt;curried&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 1 2 3 4&lt;/span&gt;
&lt;span class="nx"&gt;curried&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 1 2 3 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And did I mention that it's only 8 lines long? Let's see how I wrote it.&lt;/p&gt;




&lt;p&gt;There's a few pieces of information we need to know before we're able to write this &lt;code&gt;curry&lt;/code&gt; function. First, what the hell is going on here? If we look at how the function is used, we can see that &lt;code&gt;curry&lt;/code&gt; accepts in a function and then returns another function. There's an important thing to note here: the function that's returned &lt;em&gt;is not the same as what we passed in&lt;/em&gt;. The function that's returned will either return the value of our original function with all of the arguments somehow magically applied, or it will return &lt;em&gt;another function that accepts more arguments in&lt;/em&gt;. It might not be immediately obvious at first, but there's some kind of recursion going on in the &lt;code&gt;curry&lt;/code&gt; function because we're returning a &lt;strong&gt;different number of functions depending on the inputs to each previous function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With this in mind, we can start writing the skeleton of the &lt;code&gt;curry&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;curry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&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;recursiveSomething&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;something&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;someCondition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someArgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&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;Let's look at this line by line. Our &lt;code&gt;curry&lt;/code&gt; function accepts in an argument called &lt;code&gt;functionToCall&lt;/code&gt; that we'll eventually call (great naming, amiright?). Then on the next line, we define a recursive function that returns another function. The function name is just used here so that we're able to recursively return functions as needed; as far as I know, it isn't possible to return anonymous functions that can be called recursively in Javascript. The returned function accepts in some arguments, and depending on &lt;code&gt;someCondition&lt;/code&gt; we'll either return &lt;code&gt;functionToCall&lt;/code&gt; with some arguments passed down to it or we'll return the results of a call to &lt;code&gt;recursiveSomething&lt;/code&gt;, which is the function we're currently in. Last, we call &lt;code&gt;recursiveSomething&lt;/code&gt;, returning our conditional-return function mess.&lt;/p&gt;

&lt;p&gt;This may look pretty complicated, but we've actually got half of the function written. All that's left to do is fill in the blanks. The main problem we're trying to solve here is &lt;strong&gt;argument storage&lt;/strong&gt;: we need some place to put all of the arguments we're going to receive so that we can pass it down to our "callback function" in one go. The easiest way to do this is to just use a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters"&gt;rest parameter&lt;/a&gt;, an array to store all of the arguments in, and then just spread that array over the &lt;code&gt;functionToCall&lt;/code&gt;'s arguments when we call it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;curry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&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;let&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt; &lt;span class="o"&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;recursiveSomething&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;argumentsArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&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;someCondition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&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;Going through the lines we added, we can see that we added an array &lt;code&gt;argumentsArray&lt;/code&gt; that's outside of the &lt;code&gt;recursiveSomething&lt;/code&gt; function. This is important because it's in the scope of not only the root &lt;code&gt;recursiveSomething&lt;/code&gt; return function, but &lt;em&gt;all future returned functions&lt;/em&gt;. In the return function, we added a rest parameter (allows our function to accept in unlimited arguments and puts them in an array), and then concatenated that with the &lt;code&gt;argumentsArray&lt;/code&gt;. Last, we used &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"&gt;spread syntax&lt;/a&gt; to apply the arguments in the array to &lt;code&gt;functionToCall&lt;/code&gt; when we call it.&lt;/p&gt;

&lt;p&gt;This is great, we're actually really close to finishing our auto-curryer! We just need to fill in when we'll call &lt;code&gt;functionToCall&lt;/code&gt;, or the &lt;strong&gt;base case&lt;/strong&gt; for our recursive function. We want to call &lt;code&gt;functionToCall&lt;/code&gt; if and only if we have all of the arguments we need to actually call it. Functions in Javascript have a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length"&gt;length property&lt;/a&gt;, so we can use this to check whether the length of &lt;code&gt;argumentsArray&lt;/code&gt; is equal to the number of arguments expected by the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;curry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&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;let&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt; &lt;span class="o"&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;recursiveSomething&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;argumentsArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&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;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&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;And that's it! We can now pass &lt;code&gt;curry&lt;/code&gt; a function and it'll automatically curry all of the arguments for us thanks to the magic of recursion! Not bad for only eight lines. If you want, you can also add a few more checks to support zero argument functions and to make sure you call the function correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;curry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&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;functionToCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt; &lt;span class="o"&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;recursiveSomething&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wrong number of arguments received&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;argumentsArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&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;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;functionToCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;toCall&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;argumentsArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;recursiveSomething&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;



</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
  </channel>
</rss>
