<?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: Dan Fletcher</title>
    <description>The latest articles on Forem by Dan Fletcher (@danjfletcher).</description>
    <link>https://forem.com/danjfletcher</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%2F133226%2Fe401e2d4-b281-4396-aaca-037e0c626e53.png</url>
      <title>Forem: Dan Fletcher</title>
      <link>https://forem.com/danjfletcher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/danjfletcher"/>
    <language>en</language>
    <item>
      <title>TypeScript: Using any in Generic Constraints</title>
      <dc:creator>Dan Fletcher</dc:creator>
      <pubDate>Fri, 27 Jan 2023 19:35:09 +0000</pubDate>
      <link>https://forem.com/danjfletcher/typescript-using-any-in-generic-constraints-o11</link>
      <guid>https://forem.com/danjfletcher/typescript-using-any-in-generic-constraints-o11</guid>
      <description>&lt;h2&gt;
  
  
  Why any is bad
&lt;/h2&gt;

&lt;p&gt;They &lt;code&gt;any&lt;/code&gt; type in TypeScript is usually considered unsafe 99.99% of the time. This is why &lt;code&gt;any&lt;/code&gt; is so dangerous:&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;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I am a string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;
&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="c1"&gt;// 'I am a string'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though we're telling TS that &lt;code&gt;num&lt;/code&gt; must be of type &lt;code&gt;number&lt;/code&gt;, because the type of &lt;code&gt;str&lt;/code&gt; is &lt;code&gt;any&lt;/code&gt; it can easily be assigned to &lt;code&gt;num&lt;/code&gt; even if the value is not a &lt;code&gt;number&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Like I said, 99.99% of the time, &lt;code&gt;any&lt;/code&gt; is bad. But there is one case in TypeScript where it's completely type safe to use &lt;code&gt;any&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic constraints
&lt;/h2&gt;

&lt;p&gt;When we are working with generics in TS we can constrain the generic using the &lt;code&gt;extends&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;For example I might have a &lt;code&gt;PetOwner&lt;/code&gt; type that has a list of pets, but I want it to be generic so that I can make the array contain only cats, or only dogs.&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;PetOwner&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;pets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type will currently cause a type error because the &lt;code&gt;Array&lt;/code&gt; type requires a type argument. So lets give it one:&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;PetOwner&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;pets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now at first you may think that this is dangerous. We're using &lt;code&gt;any&lt;/code&gt;! But lets look at what actually happens when we use this type:&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;dogLover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PetOwner&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is the type of &lt;code&gt;dogLover&lt;/code&gt; here? If you gessed &lt;code&gt;{pets: Array&amp;lt;Dog&amp;gt;}&lt;/code&gt; you're correct!&lt;/p&gt;

&lt;p&gt;This is because when &lt;code&gt;any&lt;/code&gt; is used in a generic constraint, TypeScript discards it and replaces it with whatever the type argument was, assuming that it matches the constraint. &lt;code&gt;Dog[]&lt;/code&gt; matches the constraint of &lt;code&gt;Array&amp;lt;any&amp;gt;&lt;/code&gt; so &lt;code&gt;T&lt;/code&gt; gets the type &lt;code&gt;Dog[]&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠ &lt;code&gt;any&lt;/code&gt; is still dangerous if you use it as a type argument. If I instead used &lt;code&gt;PetOwner&amp;lt;any[]&amp;gt;&lt;/code&gt; it would have all the same pitfalls as using &lt;code&gt;any&lt;/code&gt; in any other context outside of a generic constraint.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A note on unknown
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;unknown&lt;/code&gt; behaves exactly the same way as &lt;code&gt;any&lt;/code&gt; in this context, so it may be preferable to use &lt;code&gt;unknown&lt;/code&gt; but it’s totally up to preference.&lt;/p&gt;

&lt;p&gt;For myself, I think &lt;code&gt;any&lt;/code&gt; reads better. It describes the intent of  the type code more clearly. T must be an array, but it can be an array of anything. Using &lt;code&gt;unknown&lt;/code&gt; doesn't convey that message as well in my opinion. &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Handle This Type Error</title>
      <dc:creator>Dan Fletcher</dc:creator>
      <pubDate>Sat, 14 Jan 2023 02:52:40 +0000</pubDate>
      <link>https://forem.com/danjfletcher/how-to-handle-this-type-error-2nc1</link>
      <guid>https://forem.com/danjfletcher/how-to-handle-this-type-error-2nc1</guid>
      <description>&lt;h1&gt;
  
  
  Can you spot the Type Error?
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&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;I posed this question on Twitter recently and it received some interesting responses:&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;The solution was intended to be rather simple, and in a way it is.&lt;/p&gt;

&lt;p&gt;However there is some interesting nuance to this problem that I hadn't considered until people started commenting. Which then took me on a journey for a much more complicated solution.&lt;/p&gt;

&lt;p&gt;For example, this comment, pointed out a flaw in my simplified version:&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;I thought it would be easier to unpack all of this in longform rather than a series of tweets.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the Type Error?
&lt;/h1&gt;

&lt;p&gt;I hope you tried to figure it out for yourself first, but here's the answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'.&lt;br&gt;
  No index signature with a parameter of type 'string' was found on type 'unknown'.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What this error is saying, is that you can't index the &lt;code&gt;obj&lt;/code&gt; parameter using &lt;code&gt;propertyName&lt;/code&gt;. Essentially TypeScript is helping you avoid a few mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 1
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;obj&lt;/code&gt; might not be an object (remember arrays are objects in JavaScript too) which would cause a runtime error when we try to do &lt;code&gt;obj[propertyName]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, what would prevent &lt;code&gt;getProperty(123, 'name')&lt;/code&gt;? Nothing. But TS prevents it with a Type Error, thankfully 🙏&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake 2
&lt;/h2&gt;

&lt;p&gt;Even if &lt;code&gt;obj&lt;/code&gt; is an object, it might not have the key that we pass as the &lt;code&gt;propertyName&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;For 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;prop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&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;age&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;In this case, &lt;code&gt;prop&lt;/code&gt; would end up &lt;code&gt;undefined&lt;/code&gt;, since &lt;code&gt;'age'&lt;/code&gt; isn't a property of &lt;code&gt;{name: 'Dan'}&lt;/code&gt; (and TS would infer &lt;code&gt;any&lt;/code&gt; as the return type from the function by the way -- also not good!)&lt;/p&gt;

&lt;h1&gt;
  
  
  The Fix
&lt;/h1&gt;

&lt;p&gt;Now that we can spot the error, and why it's an issue, how can we fix this?&lt;/p&gt;

&lt;p&gt;One approach might be to:&lt;/p&gt;

&lt;h2&gt;
  
  
  Narrow the type of T
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&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;What we've done is &lt;em&gt;narrowed&lt;/em&gt; the type of &lt;code&gt;T&lt;/code&gt; so that it's more specific. Now it has to be of type &lt;code&gt;object&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This solves the first issue mentioned above, however it only changes the message of the Type Error to be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.&lt;br&gt;
  No index signature with a parameter of type 'string' was found on type '{}'.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So instead what you could do is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&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;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&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;&lt;code&gt;Record&amp;lt;string, any&amp;gt;&lt;/code&gt; is basically saying that &lt;code&gt;T&lt;/code&gt; is an object, where the keys are strings, but the values can be anything.&lt;/p&gt;

&lt;p&gt;This will eliminate the Type Error and now the code will compile!&lt;/p&gt;

&lt;p&gt;But this has a major problem...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="c1"&gt;// prop is now `any`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&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;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Oops! prop is undefined, but no Type Error 😬&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shouldBeString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we still have the second issue mentioned above, which is that the &lt;code&gt;getProperty&lt;/code&gt; method doesn't guarantee that the property we pass exists on the object.&lt;/p&gt;

&lt;p&gt;A much better approach is to use &lt;code&gt;unknown&lt;/code&gt; instead of &lt;code&gt;any&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="c1"&gt;// prop is now `unknown`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&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;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Prop is still undefined&lt;/span&gt;
&lt;span class="c1"&gt;// But now, TypeScript will force us&lt;/span&gt;
&lt;span class="c1"&gt;// to narrow it's type before we use it.&lt;/span&gt;
&lt;span class="c1"&gt;// So this is a Type Error!&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shouldBeString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using &lt;code&gt;unknown&lt;/code&gt; instead of &lt;code&gt;any&lt;/code&gt; TS will force us to narrow the type before we use it.&lt;/p&gt;

&lt;p&gt;The snippet above will be a Type Error since &lt;code&gt;unknown&lt;/code&gt; can't be assigned to type &lt;code&gt;string&lt;/code&gt;, so now you have to write a predicate or assertion to check that &lt;code&gt;thing&lt;/code&gt; actually is of type &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡&lt;strong&gt;Tip&lt;/strong&gt;: In general if you feel the need to use &lt;code&gt;any&lt;/code&gt; in TypeScript, you should almost &lt;em&gt;always&lt;/em&gt; use &lt;code&gt;unknown&lt;/code&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is useful to have, and I want to come back to this approach but there's another, simpler way to fix the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use keyof
&lt;/h2&gt;

&lt;p&gt;The solution that I was trying to tease out of people on Twitter was to use &lt;code&gt;keyof T&lt;/code&gt; as the type constraint for &lt;code&gt;propertyName&lt;/code&gt; instead of using &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="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;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&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;Quick refresher on the &lt;code&gt;keyof&lt;/code&gt; operator:&lt;/p&gt;

&lt;p&gt;In layman's terms, &lt;code&gt;keyof&lt;/code&gt; is simply saying that a type must have a &lt;strong&gt;property of&lt;/strong&gt; the type on the right hand side of the operator.&lt;/p&gt;

&lt;p&gt;So for example if &lt;code&gt;T&lt;/code&gt; is &lt;code&gt;{name: 'Dan', age: 32}&lt;/code&gt; then &lt;code&gt;keyof T&lt;/code&gt; is really just a union of string literals 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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="s1"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember that a string literal such as &lt;code&gt;'name'&lt;/code&gt; can be a type in TypeScript.&lt;/p&gt;

&lt;p&gt;So by constraining &lt;code&gt;propertyName&lt;/code&gt; to be &lt;code&gt;keyof T&lt;/code&gt; we're saying that &lt;code&gt;propertyName&lt;/code&gt; must match one of the keys on the given &lt;code&gt;obj&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This solves both of the issues mentioned above!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="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;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="c1"&gt;// Now the Type Error is here, where we want it&lt;/span&gt;
&lt;span class="c1"&gt;// 'age' does not exist on type `{name: 'Dan'}`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&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;age&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;The nice thing about the solution above, is that it also allows the return type to be inferred properly.&lt;/p&gt;

&lt;p&gt;Here's a couple examples:&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="c1"&gt;// type will be 'string' | 'number'&lt;/span&gt;
&lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c1"&gt;// type will be 'string' | 'number'&lt;/span&gt;
&lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's pretty neat right!?&lt;br&gt;
&lt;a href="https://i.giphy.com/media/n3p6JiIG0TzCU/giphy-downsized-large.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/n3p6JiIG0TzCU/giphy-downsized-large.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  This has problems too!
&lt;/h3&gt;

&lt;p&gt;First of all, it would be nice if we received a more specific type back. Rather than &lt;code&gt;'string' | 'number'&lt;/code&gt; it would be nice if we got the actual type of the property we're pulling out of the object, right?&lt;/p&gt;

&lt;p&gt;But that's not the only problem. There's a another issue here too.&lt;/p&gt;

&lt;p&gt;This response from Twitter explains it well:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1613601410586648577-374" src="https://platform.twitter.com/embed/Tweet.html?id=1613601410586648577"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;p&gt;So with &lt;code&gt;keyof T&lt;/code&gt; alone, this function doesn't always cause Type Errors when we might expect it too.&lt;/p&gt;

&lt;p&gt;Here are a few examples where it works as expected, and others where it doesn't:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q6d0dcoctm0nga8wq92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q6d0dcoctm0nga8wq92.png" alt="A screenshot of TypeScript code detailing the examples discussed above"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why? Because JS is weird and everything that's not an object still kind of acts like one.&lt;/p&gt;

&lt;p&gt;For example, try this stuff in your JS console:&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&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;charAt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// f charAt() { [native code] }&lt;/span&gt;
&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toExponential&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// f toExponential() { [native code] }&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;valueOf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// f toValueOf() { [native code] }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So this implementation still has some weird behaviour.&lt;/p&gt;

&lt;p&gt;But what if we combined the two approaches?&lt;/p&gt;

&lt;h2&gt;
  
  
  Use both extends and keyof
&lt;/h2&gt;

&lt;p&gt;We're almost at the final solution!&lt;/p&gt;

&lt;p&gt;Let's try combining both approaches from above and see what happens. But first lets clean this function up a bit. The types are becoming a bit unruly:&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="c1"&gt;// Start by extracting the type definition to a new type alias&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Then update the function declaration to use the type&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&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;Ok great, now we can focus on just the types without the noise of the function itself getting in the way.&lt;/p&gt;

&lt;p&gt;So lets add that &lt;code&gt;&amp;lt;T extends Record&amp;lt;string, unknown&amp;gt;&amp;gt;&lt;/code&gt; bit to this implementation and see what we get:&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;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// These now cause type errors!&lt;/span&gt;
&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&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;charAt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toExponential&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;valueOf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// works as it did above but type is still 'string' | 'number'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&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;Now we've addressed every issue that's been pointed out except for one!&lt;/p&gt;

&lt;p&gt;It would be nice if when we used the &lt;code&gt;getProperty&lt;/code&gt; function that the result would be the type of the property on the original object.&lt;/p&gt;

&lt;p&gt;For example I would expect that:&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;let&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;admin&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&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;Would actually return a type &lt;code&gt;number&lt;/code&gt; and not &lt;code&gt;'string' | 'number' | 'boolean'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to do that, we can add a second type parameter to our generic called &lt;code&gt;K&lt;/code&gt; which can &lt;code&gt;extends&lt;/code&gt; the &lt;code&gt;keyof T&lt;/code&gt; - meaning that &lt;code&gt;K&lt;/code&gt; must be a type in the key of &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, so this hasn't really changed anything yet. We have to actually make use of &lt;code&gt;K&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;We want the second argument to this function to be &lt;code&gt;K&lt;/code&gt; and the return to be &lt;code&gt;T[K]&lt;/code&gt;, 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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;K&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;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now when we use this function it has none of the issues discussed above, plus we get a return type that's been narrowed to it's most specific type (like &lt;code&gt;number&lt;/code&gt; for 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;type&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;K&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;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&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;getProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propertyName&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;return&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// works as it did above but now, type is a number!!&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProperty&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;admin&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I've been on a mission to level up my competence in TypeScript lately. So learn and practice something new every morning before work (doing the #100DaysOfCode challenge).&lt;/p&gt;

&lt;p&gt;But sharing this journey in public and posing questions like the original Tweet it's really helped bring a lot of depth to my learning.&lt;/p&gt;

&lt;p&gt;I honestly thought that the answer to my question was an easy one, and it turned out to have a way deeper answer than I anticipated.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this little journey that I went on, and maybe even deepened your understanding of TypeScript too!&lt;/p&gt;

&lt;p&gt;I couldn't have written this article alone so kudos to these gems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/Nartc1410" rel="noopener noreferrer"&gt;https://twitter.com/Nartc1410&lt;/a&gt; (for the insights and poking holes in my logic)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/bitknight" rel="noopener noreferrer"&gt;https://twitter.com/bitknight&lt;/a&gt; (for proof reading, insights and suggestions)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/rgolea" rel="noopener noreferrer"&gt;https://twitter.com/rgolea&lt;/a&gt; (suggesting solutions)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Like what you read? Want to support me?&lt;/p&gt;

&lt;p&gt;A cup of coffee goes a long way 🙏&lt;/p&gt;

&lt;p&gt;Why not buy me one? &lt;a href="https://ko-fi.com/danjfletcher" rel="noopener noreferrer"&gt;https://ko-fi.com/danjfletcher&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>puzzle</category>
      <category>programming</category>
    </item>
    <item>
      <title>Type Widening Is Kinda Weird</title>
      <dc:creator>Dan Fletcher</dc:creator>
      <pubDate>Thu, 29 Dec 2022 16:51:15 +0000</pubDate>
      <link>https://forem.com/danjfletcher/type-widening-is-kinda-weird-12om</link>
      <guid>https://forem.com/danjfletcher/type-widening-is-kinda-weird-12om</guid>
      <description>&lt;p&gt;Do you notice how in TypeScript that when you initialize a variable to a boolean, string or number, that TypeScript infers the type to be exactly that? A boolean, string or number.&lt;/p&gt;

&lt;p&gt;For 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;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="c1"&gt;// is 5 since type is number not 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 Keep in mind, if you use &lt;code&gt;const&lt;/code&gt; it prefers the more specific type &lt;code&gt;4&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a huge feature of TypeScript! Type Inference is essential to writing easy to read, and maintainable TS codebases. It removes a lot of verbosity as well as reduces the amount of type code that has to be updated when a type upstream changes.&lt;/p&gt;

&lt;p&gt;However there are some times, where this can cause weird errors. For example, I didn’t guess at first glance that the below code would cause a type error:&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;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;userName&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="k"&gt;return&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;name&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you spot the error?&lt;/p&gt;

&lt;p&gt;If you caught it, great! If not, here's the issue you'll see from TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Argument of type '{ kind: string; name: string; }' is not assignable to parameter of type 'User'.
  Types of property 'kind' are incompatible.
    Type 'string' is not assignable to type '"user"'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essentially what's happening is &lt;code&gt;kind&lt;/code&gt; gets widened to type &lt;code&gt;string&lt;/code&gt; when creating the &lt;code&gt;user&lt;/code&gt; object, but the function expects &lt;code&gt;kind&lt;/code&gt; to be type &lt;code&gt;'user'&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;So what's the solution?&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;as const&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we use &lt;code&gt;as const&lt;/code&gt; it tells TypeScript that we don't want the inference to prefer the wider type of &lt;code&gt;string&lt;/code&gt; but instead use the more narrow type &lt;code&gt;'user'&lt;/code&gt;. And in this case, our error above goes away!&lt;/p&gt;




&lt;p&gt;Like what you read? Want to support me?&lt;/p&gt;

&lt;p&gt;A cup of coffee goes a long way 🙏&lt;/p&gt;

&lt;p&gt;Why not buy me one? &lt;a href="https://ko-fi.com/danjfletcher" rel="noopener noreferrer"&gt;https://ko-fi.com/danjfletcher&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Handling Exceptions In TypeScript</title>
      <dc:creator>Dan Fletcher</dc:creator>
      <pubDate>Fri, 23 Dec 2022 14:55:36 +0000</pubDate>
      <link>https://forem.com/danjfletcher/handling-exceptions-in-typescript-8j</link>
      <guid>https://forem.com/danjfletcher/handling-exceptions-in-typescript-8j</guid>
      <description>&lt;p&gt;TypeScript is all about type safety. But there are a number of situations that TypeScript can't properly guard against without a little help.&lt;/p&gt;

&lt;p&gt;Take Exceptions for example. When we wrap a &lt;code&gt;try .. catch&lt;/code&gt; around some code to handle a potential exception we probably want to do something 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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&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;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errorService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;Unfortunately TypeScript won't allow you to do this!&lt;/p&gt;

&lt;p&gt;The issue is that in JavaScript (and TypeScript) anything can be thrown as an "error". You can throw any arbitrary type; a &lt;code&gt;number&lt;/code&gt;, a &lt;code&gt;string&lt;/code&gt;, even &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is totally valid JavaScript and TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which means that our &lt;code&gt;try .. catch&lt;/code&gt; only has two options for the type hint here. &lt;code&gt;any&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;any&lt;/code&gt; type is the escape hatch out of TypeScript's type safety so we generally want to avoid that if we can help it.&lt;/p&gt;

&lt;p&gt;So we're left with &lt;code&gt;unknown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;unknown&lt;/code&gt; type in TS is a way to force users of the type, to narrow the type down to something specific. It's not valid to use something when the type is &lt;code&gt;unknown&lt;/code&gt; so we're forced to write a Type Guard.&lt;/p&gt;

&lt;p&gt;Here is the &lt;code&gt;try .. catch&lt;/code&gt; from above rewritten to use &lt;code&gt;unknown&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&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;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&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;// guaranteed to be an Error now!&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;errorService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="k"&gt;throw&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;Can't handle this error!&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a cleaner way to do this though. What if the &lt;code&gt;handle&lt;/code&gt; method dealt with the &lt;code&gt;unknown&lt;/code&gt; type instead?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ErrorService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&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="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;We don't know what the heck happened -- sorry!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// handle the error message here&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;This way the &lt;code&gt;try..catch&lt;/code&gt; outside can just pass the &lt;code&gt;unknown&lt;/code&gt; error through 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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&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;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;errorService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;Like what you read? Want to support me?&lt;/p&gt;

&lt;p&gt;A cup of coffee goes a long way 🙏&lt;/p&gt;

&lt;p&gt;Why not buy me one? &lt;a href="https://ko-fi.com/danjfletcher"&gt;https://ko-fi.com/danjfletcher&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Communication Tips For New Developers</title>
      <dc:creator>Dan Fletcher</dc:creator>
      <pubDate>Wed, 09 Jun 2021 00:56:39 +0000</pubDate>
      <link>https://forem.com/danjfletcher/communication-tips-for-new-developers-3p14</link>
      <guid>https://forem.com/danjfletcher/communication-tips-for-new-developers-3p14</guid>
      <description>&lt;p&gt;A user on the freeCodeCamp forums shared how they lost their first dev job due to lacking communication skills. I shared some of my ideas and that reply got quite a few likes so I figured it was content worth sharing here too. Here's my reply verbatim.&lt;/p&gt;




&lt;p&gt;So sorry to hear about your termination.&lt;/p&gt;

&lt;p&gt;Unfortunately it's a skill that's often not talked about much when people are presenting these "roadmaps" to becoming a developer.&lt;/p&gt;

&lt;p&gt;It's hard to give you specific advice as I don't know what project management was like or what communication channels were available to you but I can give you a few pointers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Break up tasks
&lt;/h1&gt;

&lt;p&gt;The first and most important thing is to split any tasks assigned to you into small goals that you can achieve in a very small amount of time. When someone asks you what you're working on, the answer should be different than the answer was yesterday.&lt;/p&gt;

&lt;p&gt;If your company uses Jira this may mean adding sub-tasks to the ticket you've been assigned, or it could just be writing your own notes about how you'd like to split up your work.&lt;/p&gt;

&lt;p&gt;Whether it's for a customer, a user or a project manager, splitting work up into small units makes it easier for people (including yourself) to understand the progress you've made as well as open up more opportunities for feedback before you've spent too much time on something.&lt;/p&gt;

&lt;h1&gt;
  
  
  Plan your day
&lt;/h1&gt;

&lt;p&gt;Schedule time at the beginning of your day to make a plan for yourself. Where I work we love splitting our day up into two parts; good day and great day.&lt;/p&gt;

&lt;p&gt;Every morning my team lays out what we want to accomplish today. We account for meetings and personal development time. A good rule of thumb is that for most people the average time you get to sit and be productive writing code is about 4 hours.&lt;/p&gt;

&lt;p&gt;I ask myself, if I had a good day today what would I get done? If things go really well (or great) what else might I get done on top of that?&lt;/p&gt;

&lt;p&gt;Plans can change, and so I take note of unplanned work as it comes up throughout the day. If I don't get as much as I wanted done I can either attribute that to unplanned work that came up which I had to task switch for, or it's because I underestimated how long a task would take which happens all the time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Create visibility
&lt;/h1&gt;

&lt;p&gt;Some companies have daily check-ins often called "stand up". If your company doesn't do this, do it anyway. Every morning through whatever communication channel is available to you make sure that people on your team including your manager knows what you were working on yesterday, what you plan to work on today, and if you need any help.&lt;/p&gt;

&lt;p&gt;It's important that this information actually changes day-to-day. A bad progress report sounds like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Yesterday I was working on ticket ACME-1234, it's going good, today just working on that more. No blockers."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A good one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Yesterday I finished the styles for the new contact form, today I'll be adding the frontend validation. I'm not sure if or what package I want to use for that yet so if anyone wants to give me suggestions later that would be awesome. No other blockers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Stand up" meetings aren't supposed to be "progress reports" but in reality this is what they turn into at most companies.&lt;/p&gt;

&lt;p&gt;Either way, you want this information conveyed in one form or another and you want it to change day-to-day. The way you achieve that is breaking work up into smaller tasks.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ask for help
&lt;/h1&gt;

&lt;p&gt;Do not hesitate to ask for help! It's so important. If you're stuck and can't figure something out it's better to ask for help than to spin your wheels for hours making no progress.&lt;/p&gt;

&lt;p&gt;Same rules apply when asking for help at your company as when asking questions on the freeCodeCamp forum or Stackoverflow.&lt;/p&gt;

&lt;p&gt;Make sure you've thought about your problem before asking for help. What did you try? What are you expecting to see happen? What's actually happening? etc.&lt;/p&gt;

&lt;p&gt;Or sometimes you might need feedback on how to approach a solution. Should you do it this way, or that way? Is there a better way that you didn't think of? If you've broken your work up small enough it should be easy to include someone in the discussion and go over pros and cons.&lt;/p&gt;

&lt;h1&gt;
  
  
  Under promise and over deliver
&lt;/h1&gt;

&lt;p&gt;Estimating is so hard. When building software or websites things just take longer than we think they should. Developers can be the worst at thinking something is easy and just a quick change here or there only to have the thing be a bit more nuanced or complicated than they first thought.&lt;/p&gt;

&lt;p&gt;Whenever you can, err on the side of caution. When someone asks how long something will take they will always be happier to see you get it done faster than you said it would, instead of longer than you said it would.&lt;/p&gt;

&lt;p&gt;Some managers have a way of pressuring you into over promising. Don't do it! Let them be disappointed in your estimate. It's not their estimate it's yours. They'll be a lot more upset if you appease them by giving them the estimate they want when it's not true rather than the estimate they needed which may not have been what they wanted to hear.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo regularly
&lt;/h1&gt;

&lt;p&gt;This comes back to splitting up your work into small pieces. You want to be able to show people what you've been working on as often as possible not just tell them.&lt;/p&gt;

&lt;p&gt;Quick boring demos that happen often are far better than over the moon mind blowing demos that never happen.&lt;/p&gt;

&lt;p&gt;Show people what you're working on and show it often. Doesn't have to be daily but think weekly or bi-weekly.&lt;/p&gt;

&lt;p&gt;If there is no proper channel for doing this, you can record short screen casts and share the links in Slack or whatever communication tool you use. You don't even need voice over if you're not comfortable with that. Just a quick 10-30 second demo that shows one small thing you did. You can group them together at the end of the week into one Slack post or stitch them together into one video -- whatever makes sense to you.&lt;/p&gt;

&lt;p&gt;If people are interested in seeing it, they'll look, if not, they won't. But people will definitely appreciate it and may even start following in your footsteps. I've done this for clients before and they loved it so much they started making it a part of their own internal process.&lt;/p&gt;

&lt;h1&gt;
  
  
  Take notes
&lt;/h1&gt;

&lt;p&gt;I highly recommend developers keep a daily log. It's so helpful if someone ever questions what you've been working on and they're asking you to go back more than a day. I don't know about you, but I don't actually remember what I worked on two days ago. I have to go look at my notes.&lt;/p&gt;

&lt;p&gt;This helps you cover yourself if a manager or customer asks, but it also gives you a place to jot quick notes about problems you've solved.&lt;/p&gt;

&lt;p&gt;I love to add a TIL (Today I Learned) section to my daily log where I write at least one thing a day that I learned. Sometimes it's something about the company, or something about the business domain of the client I'm working for, or something about the code base or just a cool tool or CLI I found out about. Sometimes I catch myself getting stuck on a very similar thing over and over, and if I write it down it helps me remember what I'm supposed to do in that situation going forward.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing thoughts
&lt;/h1&gt;

&lt;p&gt;Communication is probably the most important skill a developer can have. Being technically proficient is only the base requirement. I strongly believe the differentiator between successful developers and those who struggle throughout their career is communication.&lt;/p&gt;

&lt;p&gt;You have to constantly work on it and as it turns out, most developers are not as good as they could be. If you make your focus to improve on the skill at all, chances are that you'll quickly become a better communicator than most of your colleagues and rather than getting canned for being bad at it you'll find yourself getting more promotions than others for being so good at it.&lt;/p&gt;

&lt;p&gt;I also know that it could be said that good managers wouldn't let this happen in the first place which I agree. However where I work, a consultancy, we try to teach our teams to "not invite management". If you're communicating well people don't feel like they need to manage you. They also know what you're working on and when they can expect to see something. They learn to trust you because you communicate well.&lt;/p&gt;

&lt;p&gt;I really hope you find all of this helpful and good luck getting back in the game!&lt;/p&gt;




&lt;p&gt;Like what you read? Want to support me?&lt;/p&gt;

&lt;p&gt;A cup of coffee goes a long way 🙏&lt;/p&gt;

&lt;p&gt;Why not buy me one? &lt;a href="https://ko-fi.com/danjfletcher"&gt;https://ko-fi.com/danjfletcher&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Originally published here: &lt;a href="https://technicallyfletch.com/communication-tips-for-new-developers/"&gt;https://technicallyfletch.com/communication-tips-for-new-developers/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the forum thread here: &lt;a href="https://forum.freecodecamp.org/t/i-am-being-fired-after-one-month/447660"&gt;https://forum.freecodecamp.org/t/i-am-being-fired-after-one-month/447660&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>communication</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day in the life of a Scrum team</title>
      <dc:creator>Dan Fletcher</dc:creator>
      <pubDate>Thu, 03 Jun 2021 13:29:10 +0000</pubDate>
      <link>https://forem.com/danjfletcher/day-in-the-life-of-a-scrum-team-3lcm</link>
      <guid>https://forem.com/danjfletcher/day-in-the-life-of-a-scrum-team-3lcm</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;This isn't intended to be an attack on SCRUM. Just a thought experiment of a team trying to be agile and lets assume practicing continuous improvement. There are lots of problems with how they're working and they'll no doubt be brought up during the next retrospective.&lt;/p&gt;

&lt;p&gt;Think of it as a snapshot in time on any agile team. There will always be flaws in the process as they constantly experiment and improve on ideas.&lt;/p&gt;

&lt;p&gt;Personally I've seen this scenario play out a lot during my career and I think it highlights some pretty common problems that arise while we try our best to build software.&lt;/p&gt;

&lt;p&gt;I'll follow up with another article but my goal here is to highlight the inefficiencies that exist while trying to distribute work to individuals rather than working together as a group (mob programming).&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's build an app!
&lt;/h2&gt;

&lt;p&gt;So you're building some software and it's pretty involved so you make sure that there's at least 3 or 4 engineers on the project (maybe much more).&lt;/p&gt;

&lt;p&gt;You do a bit of planning and break up all the work into small deliverables. Everyone knows what they need to work on for the next two weeks and they start the sprint.&lt;/p&gt;

&lt;p&gt;So you go to Jira and grab a ticket with your name on it and it's estimated with 3 story points. You're not supposed to map story points to time, but you know from experience 3 points means you can probably get the task done in about half a day.&lt;/p&gt;

&lt;p&gt;Takes you about an hour to complete the task and submit a PR. Great! Ahead of schedule 😊 Good start to the sprint right? So you go look at your assigned tickets and grab the next one. This ticket is also a 3 pointer so you think the same amount of time (an hour to half a day or so).&lt;/p&gt;

&lt;p&gt;You're team doesn't like to have long living branches and likes to keep PR's small and concise so the normal thing to do here is to cut a new feature branch off &lt;code&gt;main&lt;/code&gt; rather than cutting a new branch off the one you submitted for code review. This works for you because your next ticket has no dependency on your previous work.&lt;/p&gt;

&lt;p&gt;So you cut a new branch off main and begin your work. About an hour in, you're still not done but there's some feedback on your PR. Normally you'd wait to go look at the review because you know the cost of task switching but your PR is actually blocking another team member from getting their work in. Usually your team tries to avoid this from happening but you missed a detail during Sprint Planning.&lt;/p&gt;

&lt;p&gt;Like a good team player you decide unblocking one of your teammates is worth the cost of task switching.&lt;/p&gt;

&lt;p&gt;So now you need to switch back to the other branch. But there's a difference in migrations plus you were playing around with some data locally that you don't want to lose. So you back that up, switch branches, rebuild your containers and reinstall dependencies and rerun migrations etc...&lt;/p&gt;

&lt;p&gt;You make the requested change from the code review and push up your work for review. The person who requested the change is now in a meeting so they can't check your updates right now. So now you don't want to just sit idle because that would be unproductive right?&lt;/p&gt;

&lt;p&gt;You make the context switch again to your other task and rebuild containers, reinstall deps, rerun migrations and import your data backup etc. By the time you remember what you were even doing the other SWE gets out of their meeting and approves your PR. Which is great! &lt;/p&gt;

&lt;p&gt;But now your PR is out of sync with the main branch and you have to rebase. But there's merge conflicts... so now you have to switch branches again to do the rebase and resolve conflicts. You rebuild, reinstall, run migrations etc...&lt;/p&gt;

&lt;p&gt;You resolve the conflicts and push up the changes but you still can't merge because you have a 2 approval requirement. The other SWE who was blocked decides to help you out by reviewing too. While he's doing that you go on to work on your other task.&lt;/p&gt;

&lt;p&gt;By the time you switch branches, and switch context all over again it's about time for lunch. After lunch you finally get some progress and you complete the task and submit a PR and add some reviewers.&lt;/p&gt;

&lt;p&gt;Meanwhile the other SWE is struggling to get your first PR running on his machine. Some crap with Docker or something... So you decide to pair up and help them sort out the situation so they can do the review.&lt;/p&gt;

&lt;p&gt;A couple hours later and after pulling other SWE's in to help you get the problem resolved and the code review continues. While you wait you decide to get some of your own work done. Before picking up a new ticket (creating more WIP) you check the code reviews and you're assigned to one.&lt;/p&gt;

&lt;p&gt;So you do some more branch switching and context changing to start a code review but it takes you a bit to get up to speed with what the task even was. By the time you are fully understanding what you're even looking at you have a scheduled 1:1 and right after that there's a design review meeting you're required to attend.&lt;/p&gt;

&lt;p&gt;The meetings are done and you have 30 minutes left until the end of the day. You try to wrap up the code review you're in the middle of but you just can't wrap your head around it after the last meeting. And now that you've sat there thinking and trying to switch contexts it's about quarter to and you figure F-it lets just go home 🤷‍♂️&lt;/p&gt;

&lt;p&gt;Next morning at standup it gets brought up that there's a lot of code sitting in review so the team decides to focus on code reviews first thing in the morning before continuing on with new work. That's great!&lt;/p&gt;

&lt;p&gt;You decide to continue on from you code review the day before since that's the branch you already have checked out. But there's also comments from yesterday sitting there unresolved on your first PR (that ticket that was supposed to take half a day to complete, remember?).&lt;/p&gt;

&lt;p&gt;By the time you finish your review and submit your comments it's already a couple hours into the morning but you can finally resolve the comments made on your first PR. Pretty easy changes but you still have to reset your local environment to work on them. And by the time you get the updates pushed up the branch has fallen way out of sync with &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you need to rebase, but yet again, there's more merge conflicts to sift through and you can't resolve these ones on your own. You want to pull another SWE in to your desk to help but they say they're too busy sorting out another issue on another PR and ask if you mind waiting until after lunch.&lt;/p&gt;

&lt;p&gt;No more reviews left for you to help with but you still have two PRs waiting to go in. Your second PR is STILL waiting for review because no one has had time to look at it yet. You're feeling pretty blocked on all your tasks and there isn't much you can do until after lunch.&lt;/p&gt;

&lt;p&gt;You're reluctant to pull more work into "in progress" with so much in the pipeline but you don't want to sit idle either so you pick up another ticket.&lt;/p&gt;

&lt;p&gt;Cut a new branch and get going on that work but then you realise you need some stuff from another branch that's still sitting in code review that you didn't think about during planning. By the time you get that far it's lunch time anyway so you just forget about it for now since it's looking like your afternoon is going to be pretty busy with other stuff anyway.&lt;/p&gt;

&lt;p&gt;Get back from lunch and that other SWE helps you resolve those merge conflicts in that first PR and get through them all but then they start taking issue with some of the changes in your work. This becomes a debate that lasts about an hour until you both agree that some of the suggested changes actually do make a lot of sense. "Ok fine." you say to yourself. "These are actually good points".&lt;/p&gt;

&lt;p&gt;Before you start the new changes you recall that someone is still blocked by some of this work getting merged in, so you pair up with them and spend a bit of time isolating the changes they need so that they can cherry-pick those changes into their branch.&lt;/p&gt;

&lt;p&gt;By this time, there's finally some comments on your 2nd PR and it also needs to be rebased. You decide since you're already in "rebase" mode you might as well just take care of it now. Switch branches, and contexts etc again, resolve the conflicts, resolve the comments, and push the updates...&lt;/p&gt;

&lt;p&gt;Now you can finally focus on making those changes to that first PR but there's an all-hands meeting. You get back, you only have 30 minutes left in the day. You try to get as much as you can but it takes you 15 minutes just to fully context switch and by the time you feel productive someone wheels their chair over to your desk and asks for help with something.&lt;/p&gt;

&lt;p&gt;Now it's 5 and time to go home and that first 3 point ticket you pulled in yesterday is still incomplete, the second 3 point ticket is still in review, you have another task that you started but haven't touched all day, and your name has been added to 2 more PRs that you haven't looked at yet and every other SWE on the project is complaining that code reviews are taking too long.&lt;/p&gt;

</description>
      <category>mobprogramming</category>
      <category>softwaredevelopment</category>
      <category>sdlc</category>
      <category>agile</category>
    </item>
  </channel>
</rss>
