<?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: Michael Sholty</title>
    <description>The latest articles on DEV Community by Michael Sholty (@msholtyfd).</description>
    <link>https://dev.to/msholtyfd</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%2F197525%2F90be03ce-75a2-46a0-a9f7-2a4a728820b7.png</url>
      <title>DEV Community: Michael Sholty</title>
      <link>https://dev.to/msholtyfd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msholtyfd"/>
    <language>en</language>
    <item>
      <title>Cohort 7 Recap</title>
      <dc:creator>Michael Sholty</dc:creator>
      <pubDate>Mon, 06 Jul 2020 12:54:35 +0000</pubDate>
      <link>https://dev.to/the-collab-lab/cohort-7-recap-ikj</link>
      <guid>https://dev.to/the-collab-lab/cohort-7-recap-ikj</guid>
      <description>&lt;p&gt;Here at &lt;a href="https://the-collab-lab.codes/"&gt;The Collab Lab&lt;/a&gt;, we've wrapped up another cohort. We couldn't be more proud of the amazing work this team has put in over the last eight weeks!&lt;/p&gt;

&lt;p&gt;First, let's take a second to appreciate the amazing work they did. Check out &lt;a href="https://tcl-7-smart-shopping-list.netlify.app/"&gt;the live application&lt;/a&gt; that this team wrote from scratch!&lt;/p&gt;

&lt;h2&gt;
  
  
  💥 Our Participants
&lt;/h2&gt;

&lt;p&gt;🐧 &lt;a href="https://www.linkedin.com/in/nabilkaz/"&gt;Nabil Kazerouni&lt;/a&gt;&lt;br&gt;
🤩 &lt;a href="https://www.linkedin.com/in/thompsondevon/"&gt;DeVon Thompson&lt;/a&gt;&lt;br&gt;
✨ &lt;a href="https://www.linkedin.com/in/meganmckissack/"&gt;Megan McKissack&lt;/a&gt;&lt;br&gt;
🏆 &lt;a href="https://www.linkedin.com/in/tanzima-chowdhury/"&gt;Tanzima Chowdhury&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  👩‍🏫 Our Mentors
&lt;/h2&gt;

&lt;p&gt;🏅 &lt;a href="https://www.linkedin.com/in/alejandronanez/"&gt;Alejandro Nanez&lt;/a&gt;&lt;br&gt;
🙌 &lt;a href="https://www.linkedin.com/in/stacietaylorcima/"&gt;Stacie Taylor&lt;/a&gt;&lt;br&gt;
🤓 &lt;a href="https://www.linkedin.com/in/michael-sholty-74233825/"&gt;Michael Sholty&lt;/a&gt; (me!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2oAfLUU7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.zappy.app/d38c8857a29e22f9cc7a5bf5a35eac90.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2oAfLUU7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.zappy.app/d38c8857a29e22f9cc7a5bf5a35eac90.png" alt="" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤩 Highlights!
&lt;/h2&gt;

&lt;p&gt;Over the last eight weeks we collaborated together &lt;em&gt;remotely&lt;/em&gt; to build an application, simulating a professional software company work environment setting. At the beginning of the week, these four would split off into two groups and pair program one of two features. At the end of the week, the pairs would present their features back to the rest of the team, talk about the ups-and-downs of the week, and plan out the following week's work.&lt;/p&gt;

&lt;p&gt;It's always amazing to watch team chemistry unfold as the weeks go on, and this team was no different. Our participants worked together like they've known each other their whole lives, which is a testament to how they are all &lt;em&gt;strong communicators&lt;/em&gt;. This is critical to succeeding in a remote environment, and they excelled way beyond expectations.&lt;/p&gt;

&lt;p&gt;It was impressive how quickly our team members picked up the tech stack and ran with it. Some of the technologies were familiar to them, like JavaScript and React. However, they had to also learn new technologies like &lt;a href="https://firebase.google.com/docs"&gt;Firebase&lt;/a&gt; to be able to get the job done 👏 👏 👏&lt;/p&gt;

&lt;p&gt;My favorite part about our this cohort was how proactive they were to owning this work. Personally I didn't have to do much to see this team succeed - they all knew how to default to action. All four team members communicated proactively early in the week to work around each other's availability, scheduled times to work and made it happen! When they ran into issues, they knew how to ask the right questions to get unblocked. These are all key qualities that I look for in teammates professionally.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎬 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;It was really an honor to get to know these folx and bond during a tumultuous time in all of our lives with COVID running amok. Here at Collab Lab, we're incredibly proud of the work our team put in, and would recommend any of our four participants for tech/programming roles in a professional setting. I know they're already talking to potential companies, so if you're looking for early-career engineers you better act fast!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using TypeScript to guard against specific React prop combinations</title>
      <dc:creator>Michael Sholty</dc:creator>
      <pubDate>Fri, 10 Apr 2020 13:43:49 +0000</pubDate>
      <link>https://dev.to/msholtyfd/using-typescript-to-guard-against-specific-react-prop-combinations-3c9a</link>
      <guid>https://dev.to/msholtyfd/using-typescript-to-guard-against-specific-react-prop-combinations-3c9a</guid>
      <description>&lt;p&gt;&lt;em&gt;Preface: I know you may see the example code here and want to refactor it, but that would defeat the purpose of the exercise. Suspend disbelief!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have a React component like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;isSquareBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;NameBadge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCircleBadge&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSquareBadge&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A NameBadge cannot both be circle and square. Please only pass in one of these props&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this example, we're writing JavaScript to warn a developer consuming this component to not misuse it. In regular JavaScript, this seems like a reasonable solution since we don't have the power of types static analysis. However, in TypeScript we can guard against this with our tooling so the developer gets immediate feedback in their editor when they misuse it, instead of hoping they see it in the console!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="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="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;IndicatorStates&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;IndicatorStates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;isSquareBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="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;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;isSquareBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;isSquareBadge&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// The point here is that you should not pass in both isCircleBadge&lt;/span&gt;
&lt;span class="c1"&gt;// and isSquareBadge as true, since a name badge can only be one shape&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;NameBadge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here I am defining explicit states that are acceptable for &lt;code&gt;isCircleBadge&lt;/code&gt; and &lt;code&gt;isSquareBadge&lt;/code&gt; boolean props. Now when you try to misuse the component, you'll get a TypeScript error instead!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ts-expect-error NameBadge must have a shape defined&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NameBadge&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Michael"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// This is fine&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NameBadge&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Michael"&lt;/span&gt; &lt;span class="na"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// So is this&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NameBadge&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Michael"&lt;/span&gt; &lt;span class="na"&gt;isSquareBadge&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// This doesn't work because NameBadge cannot have both isSquareBadge and isCircleBadge true&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NameBadge&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Michael"&lt;/span&gt; &lt;span class="na"&gt;isSquareBadge&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;isCircleBadge&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here's the error you'd get:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BopSJIPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.zappy.app/ee39e2c1c62857587b3aef3c1e821048.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BopSJIPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.zappy.app/ee39e2c1c62857587b3aef3c1e821048.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to play around with this example, please &lt;a href="https://www.typescriptlang.org/play/?jsx=2&amp;amp;ssl=1&amp;amp;ssc=1&amp;amp;pln=41&amp;amp;pc=85#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AocmATzCTgAUcwBnOAXjgG9y44A7FCCQAuOCxhRg-AOYUAvnABkcAJL8AJsDQoY0AMoxdSFhSq166rTr1RDxtu15wAPt2d8+wFgGFgUNAAbJAAhFA0ZJAB+MUkAVyQKT09vfQBHOJQiMIjosUwUQJZEjzh5ZzceZK9ffyDQ8MiYuAKikuq4VIyshtzm+PbPcr5K0pq-AOCcpvzC4qTqrszsxryWucH5MwB6bbgAFQALekhpeGOiTrYYQ904agg48UPHwI0BCHgwFBY2aTgAEafQ5XCb1aZIci7OAoTRXdLLXqRGHXKAJAA04mkaHoKAEQnoANWcB0-DgEH4gWogPoFPoLFudHISAAHpBYC04vwMMAKXAAHIEiEACjAzBYYiYEFYAEp3F5MHBReKAHTeMFTVZyqqeIgwOJQMkAHjQdWCcG2AD4FuVnHqDcatAA3C2W8i26EAARgLAAtKy6Bh-VAcFABULiSA4hI4Lcnbjnig6HANEhMNIkBpyGgKTGYCYYABGDhwI2C4QQ-HCdgAIgAstpbkhAjXXZRoUdvFcWhns7n4PmJAAmEtliO5KtIWsNtBNlugs1IqdcAaKK3tvb6CDdm7ePv8PMFgDMo-LS8n08bKGbraWPQh7BXaKQa7dUL2nbYGggJn4+HgADu0AANY0jo0b0Gelakvwnyxig8aAsC8LdCsE6wu86qLpWAz7oeEgACynuOyKCNW9ZXjeKGIg+T4JIoWGTEuj6rq6QA"&gt;check out the example in the TypeScript playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I kinda wish we could create our own TypeScript error messages for specific cases like this, but this will do for now. Hope you enjoyed my article!&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Using TypeScript Function Overloads For Distinct Component Props</title>
      <dc:creator>Michael Sholty</dc:creator>
      <pubDate>Wed, 26 Feb 2020 21:47:37 +0000</pubDate>
      <link>https://dev.to/msholtyfd/using-typescript-function-overloads-for-distinct-component-props-23l1</link>
      <guid>https://dev.to/msholtyfd/using-typescript-function-overloads-for-distinct-component-props-23l1</guid>
      <description>&lt;p&gt;Have you ever written a component that has two distinct props interfaces that can be passed in?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AspectRatioProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;aspectRatio&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;width&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;WidthHeightProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;width&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;height&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;width&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;height&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;aspectRatio&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Imagine there is some logic to handle these props&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;placeholder&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea here is that you want the consumer of this component to either pass in aspectRatio or width &amp;amp; height, but not both. &lt;/p&gt;

&lt;p&gt;Using one &lt;code&gt;Props&lt;/code&gt; interface, you can't communicate that you want one or the other. We know the two distinct interfaces are not a &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types" rel="noopener noreferrer"&gt;union&lt;/a&gt;, but you may think you can &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#intersection-types" rel="noopener noreferrer"&gt;intersection&lt;/a&gt; the types together. I'm afraid it doesn't turn out so pretty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AspectRatioProps&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;WidthHeightProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Imagine there is some logic to handle these props&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;placeholder&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzappy.zapier.com%2F0dcdc4b340a5fca7dae464998b497c74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzappy.zapier.com%2F0dcdc4b340a5fca7dae464998b497c74.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We want to be able to pass in an &lt;code&gt;aspectRatio&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; to this component, or &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt;, but not both! TypeScript seems to be not cooperating.&lt;/p&gt;

&lt;p&gt;I wouldn't be writing this article just to tell you it's not possible though! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ToMjGpKniGqRNLGBrhu/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ToMjGpKniGqRNLGBrhu/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can accomplish our goal with TypeScript function overloads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AspectRatioProps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WidthHeightProps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AspectRatioProps&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;WidthHeightProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Imagine there is some logic to handle these props&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;placeholder&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Function overloads tell your code that there are different signatures for this function. In this case, the function always returns a React element but you could even make it return different types if you wanted!&lt;/p&gt;

&lt;p&gt;Check out how TypeScript correctly validates the usage of the component in &lt;a href="https://www.typescriptlang.org/play/?jsx=1&amp;amp;ts=3.8-Beta#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wChSYBPMJOAQQGcaMEUZgIAFHMBuAXjgBvUnDgomSFmw4AuOAxhRgAOwDmAblFwA7sAAmMABbyVAVxAAjJFC0BfclRpwA6geMAJJMDVGY3CF4BYW09QxM4cysbLTEjb18YUwtrW1IHCmpaAKDBETEw4wB+ZOi0uIS-EsiUmO0JZhhWdghqxWV1e3IkAA9IWDhMMxUMDhU4AEkQFDUkAAowHgZ5RkbmjhyGAEp5ZHQYADo9jABRABskECQVGC1e-qxh0YhxqZn5xcDl13cjLx8-JsdohiIdjjBzpdrrdSPdoI8Ri1XtNZgslitJNIWps4AAfH7hf6JIEhMQAejJkxRqloxhstGAfAYuFoZwgamAaDgMAgcCMKBU+gu3PiDFon142iIMDMUHGAB59MAAG4APjAZ3QSCMEDO+hs8rJSrV6XIaBeikGEF5gnlb1m4kxTRkEH4ACIAIyyABMbrgZNVpHNKktlhQUGCdpRtEKRn4QgAzHZ-YHg6GUAAvSP22jxAEwePe5MBoMW+AgTn8pBnbPR3S-eMe5N5xKF4upssKHVnKi19718KN5MNKTOlrur2+lOlkPwBgoSgMLxnNl9h2xod8yoFoRFx1rF3uhOyAAsfoDQA" rel="noopener noreferrer"&gt;the sample code&lt;/a&gt; in a TypeScript Playground.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

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