<?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: Milosz Piechocki</title>
    <description>The latest articles on DEV Community by Milosz Piechocki (@miloszpp).</description>
    <link>https://dev.to/miloszpp</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%2F116630%2Fc4273d44-78bf-4d04-9f7a-73fe30d9c12f.jpg</url>
      <title>DEV Community: Milosz Piechocki</title>
      <link>https://dev.to/miloszpp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miloszpp"/>
    <language>en</language>
    <item>
      <title>12 Tips on Becoming a Senior Frontend Engineer</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Sat, 29 Jan 2022 18:08:19 +0000</pubDate>
      <link>https://dev.to/miloszpp/12-tips-on-becoming-a-senior-frontend-engineer-2al9</link>
      <guid>https://dev.to/miloszpp/12-tips-on-becoming-a-senior-frontend-engineer-2al9</guid>
      <description>&lt;p&gt;Have you ever wondered why the market for software engineers is so hot despite the increasing number of people learning how to code and increasing the pool of available engineers? The answer lies in the fact that while the number of engineers increases, the number of truly &lt;strong&gt;senior&lt;/strong&gt; engineers is rather small. There is much more to being senior than just writing great code. Read this article to learn about things that you can start doing to grow into seniority.&lt;/p&gt;

&lt;p&gt;The advice in this article is mostly applicable to tech companies (especially &lt;a href="https://blog.pragmaticengineer.com/what-silicon-valley-gets-right-on-software-engineers/"&gt;&lt;em&gt;Sillicon Valley-like companies&lt;/em&gt;&lt;/a&gt;) but some of the ideas might also work in more traditional companies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Career Path of a Frontend Engineer
&lt;/h2&gt;

&lt;p&gt;The career path of a Frontend Engineer is not very different from one of a backend engineer. It usually starts with the &lt;em&gt;(Junior) Software Engineer&lt;/em&gt; level, followed by &lt;em&gt;Senior Software Engineer&lt;/em&gt;. At this point, you decide whether you prefer to stay on the Individual Contributor path and become a &lt;em&gt;Staff&lt;/em&gt; or &lt;em&gt;Principal Engineer&lt;/em&gt; or switch to engineering management.&lt;/p&gt;

&lt;p&gt;Overall, the more senior you are, the more you are expected to solve problems beyond writing code. What's more, you should also be able to identify problems, propose solutions, and make sure they're solved. Another crucial aspect of seniority is visibility - in order to get promoted, you should make sure that people are familiar with and value your work. You won't accomplish this just by solving the tasks that your manager assigns to you.&lt;/p&gt;

&lt;p&gt;The subsequent paragraphs list a few ideas on improving your visibility and demonstrating seniority. I divided them into three areas: &lt;strong&gt;technical expertise&lt;/strong&gt;, &lt;strong&gt;product/UX&lt;/strong&gt;, and &lt;strong&gt;leadership&lt;/strong&gt;. You should pick one of these areas and specialize in it. However, it usually makes sense to invest a bit in the remaining two areas as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Expertise
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Idea #1: Volunteer as a Technical Lead for a new Feature/Project
&lt;/h3&gt;

&lt;p&gt;Technical Lead is not just an excellent programmer but can also lead a project end-to-end. That involves smooth communication with the stakeholders (including the Product Manager) to gather the requirements, breaking down the work into smaller tasks, proposing architecture design and discussing it with the team, coordinating the implementation (if more devs are involved), and finally, rolling out the new feature/project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #2: Improve Developer Experience
&lt;/h3&gt;

&lt;p&gt;Who's the best person to improve Developer Experience if not the developers themselves? Being challenged by problems such as long builds or unstable tests every day, you know exactly how great an impact they have on developer productivity. It may sometimes be tricky to get your manager to prioritize such work. When selling your ideas to the leadership, try to quantify the productivity loss (e.g., days of developer's time lost on waiting for the build to finish per month) and mention specific metrics that you want to improve (e.g., average build time).&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #3: Start Monitoring UI Performance
&lt;/h3&gt;

&lt;p&gt;Nowadays, UI performance is crucial to a great user experience. In some business domains, metrics such as page load time can have a direct impact on the sales of your company's product. If your company is not doing it yet, championing UI performance monitoring is a great way to increase your impact on the whole organization.&lt;/p&gt;

&lt;p&gt;Identify the key metrics that you want to track (e.g., FCP, TTI, or long tasks during interactions), start measuring them, and set up notifications for them. Present the monitoring framework to the leadership and explain how these metrics affect your company's business. An example of 3rd part software that can help you achieve that is &lt;a href="https://help.sumologic.com/Traces/Real_User_Monitoring"&gt;Sumo Logic's Real User Monitoring&lt;/a&gt; (disclaimer: I work at Sumo Logic).&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #4: Remove Some Legacy Code
&lt;/h3&gt;

&lt;p&gt;While the JavaScript framework landscape is becoming increasingly stable, many codebases went through one or two transitions in the past and still contain some traces of legacy frameworks (such as AngularJS). Such code is often a ticking bomb that nobody wants to approach. Coming up with a vision and strategy for the gradual removal of legacy code and selling the idea to the leadership is another great way of making a huge impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Influencing Product and User Experience
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Idea #5: Brainstorm some Product Ideas and Discuss with a PM
&lt;/h3&gt;

&lt;p&gt;Working on the frontend brings you very close to the product. As a by-product of developing the UI, you're constantly interacting with the product. It makes you a great source of ideas. Maintain a backlog of ideas and periodically discuss them with your PM. Focus on low-effort ideas instead of grand multiquarter projects - it would be much easier to convince your PM to put them on the roadmap. Bring some data points to back your ideas - user requests, usage statistics, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #6: Brainstorm some Usability Quick Wins and Discuss with a UX Designer
&lt;/h3&gt;

&lt;p&gt;If you feel strongly about a good User Experience, you may be better equipped to focus on usability improvements instead of new features. Feel free to interview a few users of your company's software - it's especially relevant when the company has a strong dogfooding culture. Create a list of UX improvements that would address the biggest pain points and partner up with a UX Designer to propose solutions for them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #7: Instrument the code and provide your PM with some business metrics
&lt;/h3&gt;

&lt;p&gt;Having a good understanding of how your product is being used is critical to making good product decisions. You can greatly help your PM by gathering and presenting such data. Similar to how you can use Real User Monitoring to measure UI performance, you can leverage it to collect user behavior metrics. Examples of such metrics include: the number of visits to a specific route, time spent on a specific route, number of clicks on a specific button, etc. With tools such us &lt;a href="https://help.sumologic.com/Traces/Real_User_Monitoring"&gt;Sumo Logic&lt;/a&gt; you can later create dashboards and reports with the data you collected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leadership
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Idea #8: Lead (one of the) Team Meetings
&lt;/h3&gt;

&lt;p&gt;This is a no-brainer. By volunteering to lead team meetings, you showcase and develop skills such as organization, mediation, and keeping everyone engaged. Don't hesitate to ask your Engineering Manager to lead one of the meetings - they'd gladly shed the responsibility. Be sure to prepare for the meeting in advance. Create an agenda and share it with everyone beforehand. Make sure that you stick to the schedule and cut lengthy discussions short. Collect notes and action items and send out the note after the meeting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #9: Triage Incoming Bugs
&lt;/h3&gt;

&lt;p&gt;One of the areas that often consume a lot of the Engineering Manager's time and attention is handling all the incoming bugs and urgent requests. By taking over this responsibility, you will get better at managing chaos. You'll learn how to better assess the real priority of an ask and to push back on the ones that are not urgent. Start small - talk to your Engineering Manager and ask for a trial period where he'd review your choices on a daily basis. Gradually, you'll both realize that less and less supervision is needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #10: Identify and Follow-up and Project Dependencies
&lt;/h3&gt;

&lt;p&gt;Another part of the Engineering Manager's job that you can greatly help with is nudging the owners of the dependencies of the projects your team is working on. The dependencies can include UX designs, new API (or modifications to an existing API), security review, or gathering requirements from all stakeholders. Firstly, it's important to identify the dependencies early so that other teams can plan the work in advance. Secondly, you should actively monitor progress to make sure that when you start working on the implementation, you won't get blocked on some missing pieces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #11: Propose a Process Improvement
&lt;/h3&gt;

&lt;p&gt;While &lt;em&gt;process&lt;/em&gt; may sound scary to you, it's just a name for a set of instructions that will tell everyone how to behave in a certain situation. It's like programming, but with people instead of code :) Processes make the team better organized, help build good practices and reduce ambiguity. You can propose a process for virtually anything: adding a new code dependency to the repository, handling customer escalations, onboarding a new team member, adding a new module in the repository. Create a document with a process description and share it with your colleagues so that they can provide their inputs. Design the process in a way in which it is easily enforceable. Once introduced, monitor whether the process is working as designed and search for a room for improvement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea #12: Mentor a Junior Team Member
&lt;/h3&gt;

&lt;p&gt;One of the most obvious responsibilities of a Senior Engineer is being able to grow the ones that you're working with. Set up a 1-1 with another team member. Discuss their current challenges and where they'd like to be in a year from now. Brainstorm together on how they can get there. Make sure that the work they're doing is visible to your Engineering Manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  Non-tech Companies
&lt;/h2&gt;

&lt;p&gt;As mentioned in the beginning, these ideas assume that you are working at a tech company. At such companies, developers usually have a lot of autonomy and are expected to make impact beyond writing code. You may encounter pushback when trying to implement some of these ideas in a traditional company where structures are more hierarchical and responsibilities are assigned to specific roles in a stricter way. However, don't be discouraged. I managed to do a lot of these things as an Architect in a traditional company. Sometimes, it just takes a bit of convincing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this article, we discussed what it means to be a Senior Frontend Engineer. I mentioned three different areas where you can demonstrate your seniority and listed a few ideas in each category. Hopefully, you'll find them useful! Importantly, most of these ideas will not only increase your chances of promotion but will also help you develop new skills. Let me know if you tried any of them and how they worked.&lt;/p&gt;

</description>
      <category>career</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>product</category>
    </item>
    <item>
      <title>TypeScript - Engineering Manager's perspective</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Wed, 04 Nov 2020 21:48:07 +0000</pubDate>
      <link>https://dev.to/miloszpp/typescript-engineering-manager-s-perspective-48bp</link>
      <guid>https://dev.to/miloszpp/typescript-engineering-manager-s-perspective-48bp</guid>
      <description>&lt;p&gt;&lt;strong&gt;As a Software Engineer I used to put a lot of focus on making sure that my TypeScript code is typed correctly. Actually, I deemed it to be the key code quality metric. I trusted static typing a lot, believing that the effort invested in figuring out the types pays off many times over. Now that I'm an Engineering Manager, has my perspective changed? Do I still find static typing so important?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's been a long time since I wrote on this blog. One of the reasons is my transition to an Engineering Manager role which happened about half a year ago. It's been an interesting time, which certainly changed a lot in how I approach software development. In this article, I'd like to focus on how my approach to TypeScript changed during that time.&lt;/p&gt;

&lt;p&gt;Being an Engineering Manager at the company I work in encompasses multiple responsibilities such as planning, coordinating with Product Manager and User Experience folks, taking major technical decisions, helping a Team member grow, etc. It's a breadth-first role, as opposed to Software Engineer, which is a depth-first role. The natural consequence of this is that I have less time to focus on the technical aspects, such as static typing.&lt;/p&gt;

&lt;p&gt;What's more, as an EM I have to constantly balance how much effort is spent on the product backlog versus technical debt. I realized that even in a company with a strong engineering culture, prioritizing the tech debt is tricky. There is always a lot of things to fix: increasing test coverage, fixing performance, refactoring the code after bad design choices. Improving static typing competes with a lot of other items and sometimes compromises have to be made. As a result, I'm now definitely more cautious when evaluating when it's worth spending a lot of time on improving typing in an area of code.&lt;/p&gt;

&lt;p&gt;On the other hand, as an EM I get more visibility into how static typing affects the Team's performance. And I can confirm that the majority of my SWE-era hypothesis about static typing was correct. My Team works with different parts of the product and we have to deal with noticeably more bugs in the areas that are poorly typed. What's more, poorly typed code is far less readable and more error-prone. I get regular complaints from the Team when they have to deal with such code. Also, onboarding new Team members is far easier when the code is typed correctly.&lt;/p&gt;

&lt;p&gt;One immensely helpful thing is building a Team culture that values static typing. Folks on my Team put a lot of focus on this when reviewing the code, always asking why someone typed some variable as &lt;code&gt;any&lt;/code&gt; (and they better had a really good reason) and suggesting more precise types whenever possible. This allows the team to minimize the tech debt created around static typing so that there's less to clean up later.&lt;/p&gt;

&lt;p&gt;Wrapping up, my perspective on static typing has certainly changed. I became more pragmatic about it, always evaluating the effort vs the benefit of complex type refactorings. However, fundamentally, I still believe in the importance of static typing and I would never encourage poor typing. Being an Engineering Manager allowed me to see the benefits of static typing at scale.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>leadership</category>
    </item>
    <item>
      <title>The ultimate explanation of TypeScript generics: functions</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Tue, 22 Oct 2019 20:02:55 +0000</pubDate>
      <link>https://dev.to/miloszpp/the-ultimate-explanation-of-typescript-generics-functions-1oke</link>
      <guid>https://dev.to/miloszpp/the-ultimate-explanation-of-typescript-generics-functions-1oke</guid>
      <description>&lt;p&gt;&lt;strong&gt;Originally posted on &lt;a href="https://codewithstyle.info/TypeScript-generics-demystified/"&gt;codewithstyle.info&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Recently I surveyed the readers of this blog to find out what TypeScript features people find difficult to understand. Generics were mentioned quite often. In this article, I'm going to equip you with a mental model that will let you understand &lt;strong&gt;generic functions&lt;/strong&gt; properly (I'll focus on &lt;strong&gt;generic types&lt;/strong&gt; in another article).&lt;/p&gt;

&lt;p&gt;The concept of generics is not a very new one - it has been present in different programming languages (such as Java, C# or C++) for a long time. However, for folks without background in a statically typed language, generics might appear complicated. Therefore, I'm not going to make any assumptions and will explain generics completely from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Let's say you are adding types to some JavaScript codebase and you encounter this function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&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;Typing this function is straightforward. It accepts an array of person objects as a parameter and returns an array of names (strings). For the person object, you can either create a &lt;code&gt;Person&lt;/code&gt; interface or use one that you've already created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;age&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;function&lt;/span&gt; &lt;span class="nx"&gt;getNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&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="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you notice that you don't actually need this function. Instead, you can use the built-in &lt;code&gt;Array.map&lt;/code&gt; method.&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;persons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&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="cm"&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;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;person&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmm, but what about types? You check the type of &lt;code&gt;names&lt;/code&gt; and realize that it has been correctly inferred to &lt;code&gt;string[]&lt;/code&gt;! How does TypeScript achieve such an effect?&lt;/p&gt;

&lt;p&gt;To properly understand this, let's try to type the following implementation of &lt;code&gt;map&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mappingFunction&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mappingFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&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;results&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;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;person&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main issue with typing &lt;code&gt;map&lt;/code&gt; is that you don't know anything about the type of the elements of the array it will be called with. What makes &lt;code&gt;map&lt;/code&gt; so cool is that it works with &lt;em&gt;any&lt;/em&gt; kind of array!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Works with array of Persons&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;person&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="c1"&gt;// Works with array of names too&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uppercaseNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// Works even with an array of numbers!&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;evenNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's use &lt;code&gt;any&lt;/code&gt;!
&lt;/h2&gt;

&lt;p&gt;As a first step, let's try using &lt;code&gt;any&lt;/code&gt; type to &lt;code&gt;map&lt;/code&gt; this function.&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="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;mappingFunction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break this down. &lt;code&gt;map&lt;/code&gt; has two parameters. The type of the first one (&lt;code&gt;items&lt;/code&gt;) is &lt;code&gt;any[]&lt;/code&gt;. We tell the type system that we want &lt;code&gt;items&lt;/code&gt; to be an array, but we don't care about the type of those items. The type of the second parameter (&lt;code&gt;mappingFunction&lt;/code&gt;) is a function that takes &lt;code&gt;any&lt;/code&gt; and returns &lt;code&gt;any&lt;/code&gt;. Finally, the return type is again &lt;code&gt;any[]&lt;/code&gt; - an array of &lt;em&gt;anything&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Did we gain anything by doing this? Sure! TypeScript now won't allow us to call &lt;code&gt;map&lt;/code&gt; with some nonsensical arguments:&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;// 🔴 Error: 'hello' is not an array&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&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;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&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;person&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="c1"&gt;// 🔴 Error: 1000 is not a function&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, the types we provided are not precise enough. The purpose of TypeScript is to catch possible runtime errors earlier, at compile-time. However, the following calls won't give any compile errors.&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;// The second argument is a function that only works on numbers, not on `Person` objects.&lt;/span&gt;
&lt;span class="c1"&gt;// This would result in a runtime error.&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// We tell TypeScript that `numbers` is an array of strings while in fact it will be an array of numbers.&lt;/span&gt;
&lt;span class="c1"&gt;// The second line results in a runtime error.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How can we improve the typing of &lt;code&gt;map&lt;/code&gt; so that above examples would result in a compile-time error? Enter generics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic functions
&lt;/h2&gt;

&lt;p&gt;Generic function is (in this case) a way of saying "this function works with any kind of array" and maintaining type safety at the same time.&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="nx"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TResult&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;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TElement&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;mappingFunction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TElement&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;TResult&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;TResult&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We replaced &lt;code&gt;any&lt;/code&gt; with &lt;code&gt;TElement&lt;/code&gt; and &lt;code&gt;TResult&lt;/code&gt; type parameters. Type parameters are like &lt;em&gt;named &lt;code&gt;any&lt;/code&gt;s&lt;/em&gt;. Typing &lt;code&gt;items&lt;/code&gt; as &lt;code&gt;TElement[]&lt;/code&gt; still means that it is an array of anything. However, because it's &lt;em&gt;named&lt;/em&gt;, it lets us establish relationships between types of function parameters and the return type.&lt;/p&gt;

&lt;p&gt;Here, we've just expressed the following relationships:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mappingFunction&lt;/code&gt; takes anything as a parameter, but it must be &lt;em&gt;the same type of "anything"&lt;/em&gt; as the type of elements of &lt;code&gt;items&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mappingFunction&lt;/code&gt; can return anything, but whatever type it returns, it will be used as the type of elements of the array returned by &lt;code&gt;map&lt;/code&gt; function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The picture below demonstrates these relationships. Shapes of the same color have to be of the same type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XM1nM7YJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6ow4cplbsjfrqrx5nhiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XM1nM7YJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6ow4cplbsjfrqrx5nhiw.png" alt="Generic  raw `map` endraw " width="880" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might have noticed the &lt;code&gt;&amp;lt;TElement, TResult&amp;gt;&lt;/code&gt; thing that we added next to &lt;code&gt;map&lt;/code&gt;. Type parameters have to be declared explicitly using this notation. Otherwise, TypeScript wouldn't know if &lt;code&gt;TElement&lt;/code&gt; is a type argument or an actual type.&lt;/p&gt;

&lt;p&gt;BTW, for some reason, it is a common convention to use single-character names for type parameters (with a strong preference for &lt;code&gt;T&lt;/code&gt;). I'd strongly recommend using full names, especially when you are not that experienced with generics. On the other hand, it's a good idea to prefix type arguments with &lt;code&gt;T&lt;/code&gt;, so that they're easily distinguishable from regular types.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling generic functions
&lt;/h2&gt;

&lt;p&gt;How to call a generic function? As we saw, generic functions have type parameters. These parameters are replaced with actual types "when" the function is called (technically, it's all happening at compile-time). You can provide the actual types using angle brackets notation.&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="nx"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Person&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;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;person&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine that by providing type arguments &lt;code&gt;TElement&lt;/code&gt; and &lt;code&gt;TResult&lt;/code&gt; become replaced with &lt;code&gt;Person&lt;/code&gt; and &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rfx0OTu4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kojkp6jq2kxbuzxio8ex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rfx0OTu4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kojkp6jq2kxbuzxio8ex.png" alt="Generic  raw `map` endraw " width="880" height="189"&gt;&lt;/a&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="nx"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TResult&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;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TElement&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;mappingFunction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TElement&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;TResult&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;TResult&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ...becomes...&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;mappingFunction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having to provide type arguments, when calling generic functions would be cumbersome. Fortunately, TypeScript can infer them by looking at the types of the arguments passed to the function. Therefore, we end up with the following code.&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;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;person&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoohoo! It looks exactly as the JavaScript version, except it's type-safe! Contrary to the first version of &lt;code&gt;map&lt;/code&gt;, the type of &lt;code&gt;names&lt;/code&gt; is &lt;code&gt;string[]&lt;/code&gt; instead of &lt;code&gt;any[]&lt;/code&gt;. What's more, TypeScript is now capable of throwing a compile error for the following call.&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;// 🔴 Error! Operator '+' cannot be applied to Person and 5.&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a very simplified sequence of steps that leads the compiler to throw an error.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compiler looks at the type of &lt;code&gt;persons&lt;/code&gt;. It sees &lt;code&gt;Person[]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;According to the definition of &lt;code&gt;map&lt;/code&gt;, the type of the first parameter is &lt;code&gt;TElement[]&lt;/code&gt;. Compiler deduces that &lt;code&gt;TElement&lt;/code&gt; is &lt;code&gt;Person&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compiler looks at the second parameter. It should be a function from &lt;code&gt;Person&lt;/code&gt; to &lt;code&gt;TResult&lt;/code&gt;. It doesn't know what &lt;code&gt;TResult&lt;/code&gt; is yet.&lt;/li&gt;
&lt;li&gt;It checks the body of the function provided as the second argument. It infers that the type of &lt;code&gt;n&lt;/code&gt; is &lt;code&gt;Person&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It sees that you're trying to add &lt;code&gt;5&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt;, which is of type &lt;code&gt;Person&lt;/code&gt;. This doesn't make sense, so it throws an error.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When to use generic functions?
&lt;/h2&gt;

&lt;p&gt;The good news is that, most likely, you will not be creating generic functions very often. It's much more common to call generic functions then to define them. However, it's still very useful to know how generic functions work, as it can help you better understand compiler errors.&lt;/p&gt;

&lt;p&gt;As exemplified by &lt;code&gt;map&lt;/code&gt;, functions that take arrays as parameters are often generic functions. If you look at the typings for &lt;code&gt;lodash&lt;/code&gt; library, you will see that nearly all of them are typed as generic functions. Such functions are only interested in the fact that the argument is an array, they don't care about the type of its elements.&lt;/p&gt;

&lt;p&gt;In React framework, Higher Order Components are generic functions, as they only care about the argument being a component. The type of the component's properties is not important.&lt;/p&gt;

&lt;p&gt;In RxJs, most operators are generic functions. They care about the input being and &lt;code&gt;Observable&lt;/code&gt;, but they're not interested in the type of values being emitted by the observable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Wrapping up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generic functions let you achieve type safety for functions that work with many different types of inputs;&lt;/li&gt;
&lt;li&gt;type arguments are very much like &lt;code&gt;any&lt;/code&gt; type, except they can be used to express relationships between function parameters and the return type;&lt;/li&gt;
&lt;li&gt;calling a generic function is very straightforward thanks to type inference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this article helped you finally understand generic functions. If not, please let me know!&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my book!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typescriptmasterclass.com"&gt;⭐️ Advanced TypeScript ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Two cool features coming soon to JavaScript</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Tue, 10 Sep 2019 18:19:43 +0000</pubDate>
      <link>https://dev.to/miloszpp/two-cool-features-coming-soon-to-javascript-515i</link>
      <guid>https://dev.to/miloszpp/two-cool-features-coming-soon-to-javascript-515i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Originally published on &lt;a href="https://codewithstyle.info/Two-cool-features-coming-soon-to-JavaScript/"&gt;codewithstyle.info&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recently two TC39 proposals have advanced to Stage 3.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--nSgvD9vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1003522077821792257/E_pg4iag_normal.jpg" alt="Daniel Rosenwasser profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Daniel Rosenwasser
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @drosenwasser
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      WE JUST MOVED OPTIONAL CHAINING IN JS TO STAGE 3 🎉🎉🎉🎉🎉🎉🎉
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      18:21 PM - 25 Jul 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1154456633642119168" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1154456633642119168" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1154456633642119168" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;



&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--nSgvD9vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1003522077821792257/E_pg4iag_normal.jpg" alt="Daniel Rosenwasser profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Daniel Rosenwasser
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @drosenwasser
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Today I got to present nullish coalescing at TC39 and it progressed to stage 3! The cherry on top? &lt;a href="https://twitter.com/rkirsling"&gt;@rkirsling&lt;/a&gt; already has a patch out for it in JavaScriptCore! &lt;a href="https://t.co/o3jHs2Ieo9"&gt;bugs.webkit.org/show_bug.cgi?i…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      05:53 AM - 24 Jul 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1153906097431777280" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1153906097431777280" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1153906097431777280" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;What it means to us, developers, is that two new exciting language features will soon become part of the ECMAScript standard.&lt;/p&gt;

&lt;p&gt;Let's have a quick look at these additions and see how to take advantage of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the deal with TC39 proposals?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://tc39.es"&gt;TC39&lt;/a&gt; is a group of people that drives the development of the ECMAScript (the standard of which JavaScript language is an implementation). They meet regularly to discuss proposals of new language features. Every proposal goes through a number of stages. Once it reaches Stage 4, it is ready to be included in the next version of the ECMAScript standard.&lt;/p&gt;

&lt;p&gt;When a proposal reaches Stage 3, it is already quite mature. The specification has been approved and is unlikely to change. There might already be some browsers implementing the new feature. While Stage 3 proposal is not guaranteed to become part of the standard, it's very likely to.&lt;/p&gt;

&lt;p&gt;The two proposals we're looking at are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tc39/proposal-optional-chaining"&gt;Optional Chaining for JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tc39/proposal-nullish-coalescing"&gt;Nullish Coalescing for JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Optional chaining
&lt;/h2&gt;

&lt;p&gt;Optional chaining aims to provide nice and short syntax for a very common pattern: accessing a nested property of an object in a safe way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="p"&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="s2"&gt;Acme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;London&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;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="s2"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New York&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;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="s2"&gt;Judith&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;This array contains objects representing customers. They all follow a similar structure, but some of the properties are optional. Let's say we'd like to iterate over the array and print the company name in upper case for each customer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for&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;customer&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&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="nx"&gt;toUpperCase&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;As you might have guessed, the above code is not safe. It will result in runtime errors for the second and the third array elements. We can fix it by using the following popular pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&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="nx"&gt;toUpperCase&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;Logical &lt;em&gt;and&lt;/em&gt; operator (&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;) in JavaScript behaves differently from most programming languages. It works on any value type, not only booleans. &lt;code&gt;a &amp;amp;&amp;amp; b&lt;/code&gt; translates to: if &lt;code&gt;a&lt;/code&gt; is &lt;em&gt;falsy&lt;/em&gt; (can be converted to &lt;code&gt;false&lt;/code&gt;), return &lt;code&gt;a&lt;/code&gt;. Otherwise, return &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, this solution is rather verbose. There is a lot of repetition and it gets worse the deeper the objects are nested. What's more, it checks for a value to be &lt;em&gt;falsy&lt;/em&gt;, not &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;. Therefore, it would return &lt;code&gt;0&lt;/code&gt; for the following object, while it might be preferable to return &lt;code&gt;undefined&lt;/code&gt; instead.&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional chaining comes to the rescue! With this new feature, we can shorten the above piece to a single line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;company&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="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;customer?.company&lt;/code&gt; expression will check whether &lt;code&gt;customer&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;. If this is the case, it will evaluate to &lt;code&gt;undefined&lt;/code&gt;. Otherwise, it will return &lt;code&gt;company&lt;/code&gt;. In other words, &lt;code&gt;customer?.company&lt;/code&gt; is equivalent to &lt;code&gt;customer != null ? customer : undefined&lt;/code&gt;. The new &lt;code&gt;?.&lt;/code&gt; operator is particularly useful when chained, hence the name (optional &lt;em&gt;chaining&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Be careful when replacing existing &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; chains with &lt;code&gt;?.&lt;/code&gt; operator! Bear in mind the subtle difference it treatment of falsy values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nullish coalescing
&lt;/h2&gt;

&lt;p&gt;The second proposal introduces &lt;code&gt;??&lt;/code&gt; operator which you can use to provide a default value when accessing a property/variable that you expect can be &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But hey, why not simply use &lt;code&gt;||&lt;/code&gt; for this? Similarly to &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, logical &lt;em&gt;or&lt;/em&gt; can operator on non-boolean values as well. &lt;code&gt;a || b&lt;/code&gt; returns &lt;code&gt;a&lt;/code&gt; if it's truthy, or &lt;code&gt;b&lt;/code&gt; otherwise.&lt;/p&gt;

&lt;p&gt;However, it comes with the same problem as &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; - it checks for a &lt;em&gt;truthy&lt;/em&gt; value. For example, an empty string (&lt;code&gt;''&lt;/code&gt;) will not be treated as a valid value and the default value would be returned instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customer&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no company&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// === 'no company'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nullish coalescing operator can be nicely combined with optional chaining.&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;company&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no company&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the benefit of optional chaining is clear (less verbose code), nullish coalescing is a little bit more subtle. We've all been using &lt;code&gt;||&lt;/code&gt; for providing a default value for a long time. However, this pattern can potentially be a source of nasty bugs, when a falsy value is skipped in favour of the default value. In most cases, the semantics of &lt;code&gt;??&lt;/code&gt; is what you're actually looking for.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I use it?
&lt;/h2&gt;

&lt;p&gt;Since those proposals have not reached Stage 4 yet, you need transpile the code that uses them (for example with Babel). You can play with &lt;a href="https://babeljs.io/repl"&gt;Babel's on-line REPL&lt;/a&gt; to see what do they get compiled to.&lt;/p&gt;

&lt;p&gt;At the moment of writing, optional chaining is &lt;a href="https://www.chromestatus.com/feature/5748330720133120"&gt;available in Chrome behind a feature flag&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Optional chaining will also be available in the upcoming &lt;a href="https://github.com/microsoft/TypeScript/issues/16#issuecomment-515160784"&gt;TypeScript 3.7 release&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Recent ECMAScript versions didn't bring many syntactical additions to the language. It's likely to change with the next edition. Some people say that JavaScript is getting bloated. I personally think that these two pieces of syntactic sugar are long overdue, as they've been available in many modern programming languages and they address real-life, common development scenarios.&lt;/p&gt;

&lt;p&gt;What do you think? 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my book!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typescriptmasterclass.com"&gt;⭐️ Advanced TypeScript ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Using React useState hook with TypeScript</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Thu, 22 Aug 2019 20:51:18 +0000</pubDate>
      <link>https://dev.to/miloszpp/using-react-usestate-hook-with-typescript-3d3h</link>
      <guid>https://dev.to/miloszpp/using-react-usestate-hook-with-typescript-3d3h</guid>
      <description>&lt;p&gt;React hooks are a recent addition to React that make function components have almost the same capabilities as class components. Most of the time, using React hooks in TypeScript is straightforward. &lt;/p&gt;

&lt;p&gt;However, there are some situations when deeper understanding of hooks' types might prove very useful. In this article, we're going to focus on the &lt;code&gt;useState&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;I'm going to assume that you have a basic understanding of this hook. If this is not the case, please read &lt;a href="https://reactjs.org/docs/hooks-state.html"&gt;this&lt;/a&gt; first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading the types
&lt;/h2&gt;

&lt;p&gt;First of all, let's take a look at the type signature of &lt;code&gt;useState&lt;/code&gt;. You'll see how much information you can extract solely from types, without looking at the docs (or the implementation).&lt;/p&gt;

&lt;p&gt;If you're only interested in practical examples, skip to the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overloads
&lt;/h3&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="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;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;S&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SetStateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&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;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SetStateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="o"&gt;&amp;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;As you can see, there are two &lt;em&gt;versions&lt;/em&gt; of &lt;code&gt;useState&lt;/code&gt; function. TypeScript lets you define multiple type signatures for a function as it is often the case in JavaScript that a function supports different types of parameters. Multiple type signatures for a single function are called &lt;strong&gt;overloads&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Both overloads are generic functions. The type parameter &lt;code&gt;S&lt;/code&gt; represents the type of the piece of state stored by the hook. The type argument in the second overload can be inferred from &lt;code&gt;initialState&lt;/code&gt;. However, in the first overload, it defaults to &lt;code&gt;undefined&lt;/code&gt; unless the type argument is explicitly provided. &lt;strong&gt;If you don't pass initial state to &lt;code&gt;useState&lt;/code&gt;, you should provide the type argument explicitly.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;useState&lt;/code&gt; parameters
&lt;/h3&gt;

&lt;p&gt;The first overload doesn't take any parameters - it's used when you call &lt;code&gt;useState&lt;/code&gt; without providing any initial state.&lt;/p&gt;

&lt;p&gt;The second overload accepts &lt;code&gt;initialState&lt;/code&gt; as parameter. It's type is a union of &lt;code&gt;S&lt;/code&gt; and &lt;code&gt;() =&amp;gt; S&lt;/code&gt;. Why would you pass a function that returns initial state instead of passing the initial state directly? Computing initial state can be expensive. It's only needed during when the component is mounted. However, in a function component, it would be calculated on every render. &lt;strong&gt;Therefore, you have an option to pass a function that calculates initial state - expensive computation will only be executed once, not on every render.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;useState&lt;/code&gt; return type
&lt;/h3&gt;

&lt;p&gt;Let's move to the return type. It's a &lt;strong&gt;tuple&lt;/strong&gt; in both cases. Tuple is like an array that has a specific length and contains elements with specific types.&lt;/p&gt;

&lt;p&gt;For the second overload, the return type is &lt;code&gt;[S, Dispatch&amp;lt;SetStateAction&amp;lt;S&amp;gt;&amp;gt;]&lt;/code&gt;. The first element of the tuple has type &lt;code&gt;S&lt;/code&gt; - the type of the piece of state. It will contain the value retrieved from the component's state.&lt;/p&gt;

&lt;p&gt;The second element's type is &lt;code&gt;Dispatch&amp;lt;SetStateAction&amp;lt;S&amp;gt;&amp;gt;&lt;/code&gt;. &lt;code&gt;Dispatch&amp;lt;A&amp;gt;&lt;/code&gt; is simply defined as &lt;code&gt;(value: A) =&amp;gt; void&lt;/code&gt; - a function that takes a value and doesn't return anything. &lt;code&gt;SetStateAction&amp;lt;S&amp;gt;&lt;/code&gt; is defined as &lt;code&gt;S | ((prevState: S) =&amp;gt; S)&lt;/code&gt;. Therefore, the type of &lt;code&gt;Dispatch&amp;lt;SetStateAction&amp;lt;S&amp;gt;&amp;gt;&lt;/code&gt; is actually &lt;code&gt;(value: S | ((prevState: S) =&amp;gt; S)) =&amp;gt; void&lt;/code&gt;. It is a function that takes either an updated version of the piece of state OR a function that produces the updated version based on the previous version. In both cases, we can deduce that the second element of the tuple returned by &lt;code&gt;setState&lt;/code&gt; is a function that we can call to update the component's state.&lt;/p&gt;

&lt;p&gt;The return type of the first overload is the same, but here instead of &lt;code&gt;S&lt;/code&gt;, &lt;code&gt;S | undefined&lt;/code&gt; is used anywhere. If we don't provide initial state it will store &lt;code&gt;undefined&lt;/code&gt; initially. It means that &lt;code&gt;undefined&lt;/code&gt; has to be included in the type of the piece of state stored by the hook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage examples
&lt;/h2&gt;

&lt;p&gt;Most of the time you don't need to bother with providing type arguments to &lt;code&gt;useState&lt;/code&gt; - the compiler will infer the correct type for you. However, in some situations type inference might not be enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Empty initial state
&lt;/h3&gt;

&lt;p&gt;The first type of situation is when you don't want to provide initial state to &lt;code&gt;useState&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;As we saw in the type definition, the type argument &lt;code&gt;S&lt;/code&gt; for the parameterless defaults to &lt;code&gt;undefined&lt;/code&gt;. Therefore, the type of &lt;code&gt;pill&lt;/code&gt; should be inferred to &lt;code&gt;undefined&lt;/code&gt;. However, due to a &lt;a href="https://github.com/microsoft/TypeScript/issues/32003"&gt;design limitation in TypeScript&lt;/a&gt;, it's actually inferred to &lt;code&gt;any&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Similarly, &lt;code&gt;setPill&lt;/code&gt;'s type is inferred to &lt;code&gt;React.Dispatch&amp;lt;any&amp;gt;&lt;/code&gt;. It's really bad, as nothing would stop us from calling it with invalid argument: &lt;code&gt;setPill({ hello: 5 })&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PillSelector&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;FunctionComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Red&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blue&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;chose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;In order to fix this issue, we need to pass a type argument to &lt;code&gt;setState&lt;/code&gt;. We treat &lt;code&gt;pill&lt;/code&gt; as text in JSX, so our fist bet could be &lt;code&gt;string&lt;/code&gt;. However, let's be more precise and limit the type to only allow values that we expect.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&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;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&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;Note that the inferred type of &lt;code&gt;pill&lt;/code&gt; is now &lt;code&gt;"red" | "blue" | undefined&lt;/code&gt; (because this piece of state is initially empty). With &lt;code&gt;strictNullChecks&lt;/code&gt; enabled TypeScript wouldn't let us call anything on &lt;code&gt;pill&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="c1"&gt;// 🛑 Object is possibly 'undefined'.ts(2532)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;chose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...unless we check the value first:&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;// ✅ No errors!&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;chose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clearable state
&lt;/h3&gt;

&lt;p&gt;Another kind of situation when you would provide a type argument to &lt;code&gt;useState&lt;/code&gt; is when initial state is defined, but you want to be able to &lt;strong&gt;clear&lt;/strong&gt; the state later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PillSelector&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;FunctionComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&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;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Red&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blue&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="c1"&gt;// 🛑 Argument of type 'undefined' is not assignable &lt;/span&gt;
        &lt;span class="c1"&gt;// to parameter of type 'SetStateAction&amp;lt;string&amp;gt;'.&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&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;Reset&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;chose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since initial state is passed to &lt;code&gt;useState&lt;/code&gt;, the type of &lt;code&gt;pill&lt;/code&gt; gets inferred to &lt;code&gt;string&lt;/code&gt;. Therefore, when you try to pass &lt;code&gt;undefined&lt;/code&gt; to it, TypeScript will error.&lt;/p&gt;

&lt;p&gt;You can fix the problem by providing the type argument.&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPill&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&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;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&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;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Wrapping up, we've analysed the type definitions of &lt;code&gt;useState&lt;/code&gt; function thoroughly. Based on this information, we saw when providing the type argument to &lt;code&gt;useState&lt;/code&gt; might be necessary and when the inferred type is sufficient.&lt;/p&gt;

&lt;p&gt;I like how hooks are great example of how much information can be read from type definitions. They really show off the power of static typing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my book!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typescriptmasterclass.com"&gt;⭐️ Advanced TypeScript ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>hooks</category>
      <category>generics</category>
    </item>
    <item>
      <title>Typing Higher Order Components in React</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Thu, 15 Aug 2019 21:25:45 +0000</pubDate>
      <link>https://dev.to/miloszpp/typing-higher-order-components-in-react-2c57</link>
      <guid>https://dev.to/miloszpp/typing-higher-order-components-in-react-2c57</guid>
      <description>&lt;p&gt;Some time ago &lt;a href="https://codewithstyle.info/TypeScript-3-4-hidden-gem-propagated-generic-type-arguments/" rel="noopener noreferrer"&gt;I wrote about&lt;/a&gt; generic type arguments propagation feature added in TypeScript version 3.4. I explained how this improvement makes point-free style programming possible in TypeScript. &lt;/p&gt;

&lt;p&gt;As it turns out, there are more cases in which propagation of generic type arguments is desirable. One of them is passing a generic component to a Higher Order Component in React.&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post is inspired by the problem &lt;a href="https://twitter.com/fbartho" rel="noopener noreferrer"&gt;Frederic Barthelemy&lt;/a&gt; tweeted about and asked me to have a look at.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Higher Order Components
&lt;/h2&gt;

&lt;p&gt;I'm not going to give a detailed explanation, as there are already plenty to be found on the internet. &lt;strong&gt;Higher Order Component (HOC)&lt;/strong&gt; is a concept of the React framework that lets you abstract cross-cutting functionality and provide it to multiple components.&lt;/p&gt;

&lt;p&gt;Technically, HOC is a function that takes a component and returns another component. It usually augments the source component with some behavior or provides some properties required by the source component.&lt;/p&gt;

&lt;p&gt;Here is an example of a HOC in 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withLoadingIndicator&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;P&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;Component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ComponentType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&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;ComponentType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&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="o"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;isLoading&lt;/span&gt; 
                &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can deduce from the type signature, &lt;code&gt;withLoadingIndicator&lt;/code&gt; is a function that accepts a component with &lt;code&gt;P&lt;/code&gt;-shaped properties and returns a component that additionally has &lt;code&gt;isLoading&lt;/code&gt; property. It adds the behavior of displaying loading indicator based on &lt;code&gt;isLoading&lt;/code&gt; property.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftiskeso5c9v7pyvaa0tj.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftiskeso5c9v7pyvaa0tj.png" alt="HOC type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem: passing a generic component to a HOC
&lt;/h2&gt;

&lt;p&gt;So far so good. However, let's imagine that we have a &lt;strong&gt;generic component&lt;/strong&gt; &lt;code&gt;Header&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;class&lt;/span&gt; &lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TContent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;extends&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;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HeaderProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TContent&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...where &lt;code&gt;HeaderProps&lt;/code&gt; is a generic type that represents &lt;code&gt;Header&lt;/code&gt;'s props given the type of associated content (&lt;code&gt;TContent&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;type&lt;/span&gt; &lt;span class="nx"&gt;HeaderProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TContent&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;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TContent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;title&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's use &lt;code&gt;withLoadingIndicator&lt;/code&gt; with this &lt;code&gt;Header&lt;/code&gt; component.&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;HeaderWithLoader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withLoadingIndicator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The question is, what is the inferred type of &lt;code&gt;HeaderWithLoader&lt;/code&gt;? Unfortunately, it's &lt;code&gt;React.ComponentType&amp;lt;HeaderProps&amp;lt;unknown&amp;gt; &amp;amp; { isLoading: boolean; }&amp;gt;&lt;/code&gt; in TypeScript 3.4 and later or &lt;code&gt;React.ComponentType&amp;lt;HeaderProps&amp;lt;{}&amp;gt; &amp;amp; { isLoading: boolean; }&amp;gt;&lt;/code&gt; in previous versions. &lt;/p&gt;

&lt;p&gt;As you can see, &lt;code&gt;HeaderWithLoader&lt;/code&gt; is &lt;strong&gt;not&lt;/strong&gt; a generic component. In other words, generic type argument of &lt;code&gt;Header&lt;/code&gt; was &lt;strong&gt;not propagated&lt;/strong&gt;. Wait... doesn't TypeScript 3.4 introduce generic type argument propagation?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution: use function components!
&lt;/h2&gt;

&lt;p&gt;Actually, it does. However, it only works for &lt;strong&gt;functions&lt;/strong&gt;. &lt;code&gt;Header&lt;/code&gt; is a generic class, not a generic function. Therefore, the improvement introduced in TypeScript 3.4 doesn't apply here ☹️&lt;/p&gt;

&lt;p&gt;Fortunately, we have &lt;strong&gt;function components&lt;/strong&gt; in React. We can make type argument propagation work if we limit &lt;code&gt;withLoadingIndicator&lt;/code&gt; to only work with function components.&lt;/p&gt;

&lt;p&gt;Unfortunately, we cannot use &lt;code&gt;FunctionComponent&lt;/code&gt; type since it is defined as an interface, not a function type. However, a function component is nothing else but a generic function that takes props and returns &lt;code&gt;React.ReactElement&lt;/code&gt;. Let's define our own type representing function components.&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;SimpleFunctionComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;P&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;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="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withLoadingIndicator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&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;Component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SimpleFunctionComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SimpleFunctionComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;By using &lt;code&gt;SimpleFunctionComponent&lt;/code&gt; instead of &lt;code&gt;FunctionComponent&lt;/code&gt; we loose access to properties such as &lt;code&gt;defaultProps&lt;/code&gt;, &lt;code&gt;propTypes&lt;/code&gt;, etc., which we don't need anyway.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Obviously, we need to change &lt;code&gt;Header&lt;/code&gt; to be a function component, not a class component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TContent&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;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeaderProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TContent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;We wouldn't be able to use &lt;code&gt;FunctionComponent&lt;/code&gt; here anyway, since &lt;code&gt;Header&lt;/code&gt; is a generic component&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's now take a look at the inferred type of &lt;code&gt;HeaderWithLoader&lt;/code&gt;. It's...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;TContent&amp;gt;(props: HeaderProps&amp;lt;TContent&amp;gt; &amp;amp; { isLoading: boolean }) =&amp;gt; React.ReactElement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which looks very much like a generic function component!&lt;/p&gt;

&lt;p&gt;Indeed, we can use &lt;code&gt;Header&lt;/code&gt; as a regular component in JSX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HeaderWithLoader&lt;/span&gt; 
                &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
                &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Most importantly, &lt;code&gt;HeaderWithLoader&lt;/code&gt; is typed correctly!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;As you can see, typing HOCs in React can get tricky. The proposed solution is really a workaround - ideally, TypeScript should be able to propagate generic type arguments for all generic types (not only functions). &lt;/p&gt;

&lt;p&gt;Anyway, this example demonstrates how important it is to stay on top of the features introduced in new TypeScript releases. Before version 3.4, it wouldn't be even possible to get this HOC typed correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my book!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typescriptmasterclass.com" rel="noopener noreferrer"&gt;⭐️ Advanced TypeScript ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>functional</category>
      <category>react</category>
      <category>generics</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Strict function types in TypeScript: covariance, contravariance and bivariance</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Mon, 29 Jul 2019 20:29:24 +0000</pubDate>
      <link>https://dev.to/miloszpp/strict-function-types-in-typescript-covariance-contravariance-and-bivariance-53kc</link>
      <guid>https://dev.to/miloszpp/strict-function-types-in-typescript-covariance-contravariance-and-bivariance-53kc</guid>
      <description>&lt;p&gt;Let's talk about one of the less well known strict type checking options - &lt;code&gt;strictFunctionTypes&lt;/code&gt;. It helps you avoid another class of bugs, and it's also an excellent opportunity to learn about some fundamental computer science concepts: &lt;strong&gt;covariance&lt;/strong&gt;, &lt;strong&gt;contravariance&lt;/strong&gt;, and &lt;strong&gt;bivariance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Strict function type checking was introduced in TypeScript 2.6. Its definition in TypeScript documentation refers to an enigmatic term: &lt;strong&gt;bivariance&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disable bivariant parameter checking for function types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What bugs can &lt;code&gt;strictFunctionTypes&lt;/code&gt; catch?
&lt;/h2&gt;

&lt;p&gt;First of all, let's see an example of a bug that can be caught by enabling this flag.&lt;/p&gt;

&lt;p&gt;In the following example, &lt;code&gt;fetchArticle&lt;/code&gt; is a function that accepts a callback to be executed after an article is fetched from some backend service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchArticle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Interestingly, TypeScript with default settings compiles the following code without errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ArticleWithContent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;fetchArticle&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ArticleWithContent&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&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, this code can result in a runtime error. The function passed as a callback to &lt;code&gt;fetchArticle&lt;/code&gt; only knows how to deal with with a specific subset of &lt;code&gt;Article&lt;/code&gt; objects - those that also have &lt;code&gt;content&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;However, &lt;code&gt;fetchArticle&lt;/code&gt; can fetch all kinds of articles - including those that only have &lt;code&gt;title&lt;/code&gt; defined. In such case, &lt;code&gt;r.content&lt;/code&gt; is undefined, and runtime exception is thrown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: undefined is not an object (evaluating 'r.content.toLowerCase')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Fortunately, enabling &lt;code&gt;strictFunctionTypes&lt;/code&gt; results in a &lt;strong&gt;compile-time error&lt;/strong&gt;. A compile-time error is always better than a runtime error, as it surfaces before users run your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Argument of type '(r: ArticleWithContent) =&amp;gt; void' is not assignable to parameter of type '(article: Article) =&amp;gt; void'.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Covariance, contravariance, and bivariance
&lt;/h2&gt;

&lt;p&gt;If you just wanted to learn what &lt;code&gt;strictFunctionTypes&lt;/code&gt; does, you can stop reading right now. However, I encourage you to follow along and learn some background behind this check.&lt;/p&gt;

&lt;p&gt;First, let's introduce a type to represent generic single-argument callbacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Callback&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchArticle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Callback&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Callback&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ArticleWithContent&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;fetchArticle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The reason &lt;code&gt;fetchArticle&lt;/code&gt; shouldn't accept &lt;code&gt;callback&lt;/code&gt; is that the callback is too specific. It only works on a subset of things that can be fed into it.&lt;/p&gt;

&lt;p&gt;The type of &lt;code&gt;callback&lt;/code&gt; should not be assignable to the type of &lt;code&gt;onSuccess&lt;/code&gt; parameter. &lt;/p&gt;

&lt;p&gt;In other words, the fact that &lt;code&gt;ArticleWithContent&lt;/code&gt; is assignable to &lt;code&gt;Article&lt;/code&gt; does &lt;em&gt;not&lt;/em&gt; imply that&lt;br&gt;
&lt;code&gt;Callback&amp;lt;ArticleWithContent&amp;gt;&lt;/code&gt; is assignable to &lt;code&gt;Callback&amp;lt;Article&amp;gt;&lt;/code&gt;. If such implication were true, &lt;code&gt;Callback&lt;/code&gt; type would be &lt;strong&gt;covariant&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In our case, the opposite is true - &lt;code&gt;Callback&amp;lt;Article&amp;gt;&lt;/code&gt; is assignable to &lt;code&gt;Callback&amp;lt;ArticleWithContent&amp;gt;&lt;/code&gt;. That's because a callback that can handle all articles is also able to handle &lt;code&gt;ArticleWithContent&lt;/code&gt;. Therefore, &lt;code&gt;Callback&lt;/code&gt; is &lt;strong&gt;contravariant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If both implications were true at the same time, then &lt;code&gt;Callback&lt;/code&gt; would be &lt;strong&gt;bivariant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's now revisit the definition of &lt;code&gt;strictFunctionTypes&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disable bivariant parameter checking for function types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Does it make sense now? With the check enabled, function type parameter positions are checked contravariantly instead of bivariantly.&lt;/p&gt;

&lt;p&gt;On a side note, some function types are excluded from strict function type checks - e.g., function arguments to methods and constructors are still checked bivariantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Wrapping up, &lt;code&gt;strictFunctionTypes&lt;/code&gt; is a useful compiler flag that helps you catch a class of bugs related to passing function arguments, such as callbacks. &lt;/p&gt;

&lt;p&gt;The concept behind this flag is contravariance, which is a property of a type (type constructor, strictly speaking) that describes its assignability with respect to its type argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my course!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.educative.io/courses/advanced-typescript-masterclass"&gt;⭐️ Advanced TypeScript Masterclass ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>strictmode</category>
    </item>
    <item>
      <title>5 Commandments for TypeScript programmers</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Wed, 17 Jul 2019 15:54:12 +0000</pubDate>
      <link>https://dev.to/miloszpp/5-commandments-for-typescript-programmers-2jp1</link>
      <guid>https://dev.to/miloszpp/5-commandments-for-typescript-programmers-2jp1</guid>
      <description>&lt;p&gt;More and more projects and teams are adopting TypeScript. However, there is a massive difference between just using TypeScript and taking the most out of it. &lt;/p&gt;

&lt;p&gt;I present to you this list of high-level TypeScript best practices that will help you take advantage of TypeScript to the fullest possible extent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article is also available in Russian: &lt;a href="https://habr.com/ru/post/461565"&gt;5 заповедей TypeScript-разработчика&lt;/a&gt;&lt;/strong&gt; (by &lt;a href="https://dev.to/bevalorous"&gt;Vadim Belorussov&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not lie
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Types are a contract.&lt;/strong&gt; What does it mean? When you implement a function, its type is a promise to other developers (or to your future self!) that when they call it, it will return a specific kind of value.&lt;/p&gt;

&lt;p&gt;In the following example, the type of &lt;code&gt;getUser&lt;/code&gt; promises that it will return an object that will &lt;strong&gt;always&lt;/strong&gt; have two properties: &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&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;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;TypeScript is a very flexible language. It's full of compromises made in order to make its adoption easier. For example, it allows you to implement &lt;code&gt;getUser&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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="k"&gt;return&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;12&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Don't do this! It's a LIE. By doing this, you LIE to other developers (who will use this function in their functions). They expect the object returned by &lt;code&gt;getUser&lt;/code&gt; to always have some &lt;code&gt;name&lt;/code&gt;. But it doesn't! Then, what happens when your teammate writes &lt;code&gt;getUser(1).name.toString()&lt;/code&gt;? You know it well...&lt;/p&gt;

&lt;p&gt;Of course, this lie seems very obvious. However, when working with a huge codebase, you will often find yourself in a situation when a value you want to return (or pass) &lt;em&gt;almost&lt;/em&gt; matches the expected type. &lt;strong&gt;Figuring out the reason for type mismatch takes time and effort&lt;/strong&gt; and you are in a hurry... so you decide to cast. &lt;/p&gt;

&lt;p&gt;However, by doing this, you &lt;strong&gt;violate the holy contract&lt;/strong&gt;. It's ALWAYS better to take time to figure out why types do not match than to do the cast. It's very likely that some runtime bug is lurking under the surface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't lie. Respect your contracts.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Be precise
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Types are documentation.&lt;/strong&gt; When you document a function, don't you want to convey as much information as possible?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Returns an object&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Returns an object with two properies: name and age&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// If id is a number and a user with given id exists,&lt;/span&gt;
&lt;span class="c1"&gt;// returns an object with two properies: name and age.&lt;/span&gt;
&lt;span class="c1"&gt;// Otherwise, returns undefined.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which comment for &lt;code&gt;getUser&lt;/code&gt; would you prefer? The more you know about what it returns, the better. For example, knowing that it could return &lt;code&gt;undefined&lt;/code&gt;, you can write an &lt;code&gt;if&lt;/code&gt; statement to check if the value it returned is defined before accessing its properties.&lt;/p&gt;

&lt;p&gt;It's exactly the same with types. The more precise a type is, the more information it conveys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standard&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;premium&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;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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 second version of &lt;code&gt;getUserType&lt;/code&gt; is much more informative, and hence it puts the caller in a much better situation. It's easier to handle a value if you know that it is &lt;strong&gt;for sure&lt;/strong&gt; (contracts, remember?) one of the three strings than if it can be any string. For starters, you know for sure that the value is not an empty string.&lt;/p&gt;

&lt;p&gt;Let's see a more realistic example. &lt;code&gt;State&lt;/code&gt; type represents the state of a component that fetches some data from the backend. Is this type precise?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&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;The consumer of this type must handle some unlikely combinations of property values. For example, it's not possible that both &lt;code&gt;data&lt;/code&gt; and &lt;code&gt;errorMessage&lt;/code&gt; will be defined (data fetching can either be successful or result in an error). &lt;/p&gt;

&lt;p&gt;We can make the type much more precise with the help of discriminated union types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;State&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;successful&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&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;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, the consumer of this type has much more information. They don't need to handle illegal combinations of property values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be precise. Convey as much information as possible in your types.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with types
&lt;/h2&gt;

&lt;p&gt;Since types are both contract and documentation, they're great for &lt;strong&gt;designing&lt;/strong&gt; your functions (or methods).&lt;/p&gt;

&lt;p&gt;There are many articles around in the internet that advise software engineers to &lt;strong&gt;think before they write code&lt;/strong&gt;. I totally agree with this approach. It's tempting to jump straight into code, but it often leads to some bad decisions. Spending some time thinking about the implementation always pays off.&lt;/p&gt;

&lt;p&gt;Types are super helpful in this process. &lt;em&gt;Thinking&lt;/em&gt; can result in writing down the type signatures of functions involved in your solution. It's awesome because it lets you focus on &lt;em&gt;what&lt;/em&gt; your functions do instead of &lt;em&gt;how&lt;/em&gt; they achive it.&lt;/p&gt;

&lt;p&gt;React JS has a concept of Higher Order Components. They are functions that augment given component in some way. For example, you could create a &lt;code&gt;withLoadingIndicator&lt;/code&gt; Higher Order Component that adds a loading indicator to an existing component.&lt;/p&gt;

&lt;p&gt;Let's write the type signature for this function. It takes a component and returns a component. We can use React's &lt;code&gt;ComponentType&lt;/code&gt; to indicate a component.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ComponentType&lt;/code&gt; is a generic type parameterized by the type of properties of the component. &lt;code&gt;withLoadingIndicator&lt;/code&gt; takes a component and returns a new component that either shows the original component or shows a loading indicator. The decision is made based on the value of a new boolean property &lt;code&gt;isLoading&lt;/code&gt;. Therefore, the resulting component should require the same properties as the original component plus the new property.&lt;/p&gt;

&lt;p&gt;Let's finalize the type. &lt;code&gt;withLoadingIndicator&lt;/code&gt; takes a component of type &lt;code&gt;ComponentType&amp;lt;P&amp;gt;&lt;/code&gt; where &lt;code&gt;P&lt;/code&gt; denotes the type of the properties. It returns a component with augmented properties of type &lt;code&gt;P &amp;amp; { isLoading: boolean }&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;withLoadingIndicator&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;P&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;Component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ComponentType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;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;ComponentType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Figuring out the type of this function forced us to think about its input and its output. In other words, it made us &lt;em&gt;design it&lt;/em&gt;. Writing the implementation is a piece of cake now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with types. Let types force you to design before implementing.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Embrace strictness
&lt;/h2&gt;

&lt;p&gt;The first three points require you to pay a lot of attention to types. Fortunately, you are not alone in the task - TypeScript compiler will often let you know when your types lie or when they're not precise enough.&lt;/p&gt;

&lt;p&gt;You can make the compiler even more helpful by enabling &lt;code&gt;--strict&lt;/code&gt; compiler flag. It is a meta flag that enables all strict type checking options: &lt;code&gt;--noImplicitAny&lt;/code&gt;, &lt;code&gt;--noImplicitThis&lt;/code&gt;, &lt;code&gt;--alwaysStrict&lt;/code&gt;, &lt;code&gt;--strictBindCallApply&lt;/code&gt;, &lt;code&gt;--strictNullChecks&lt;/code&gt;, &lt;code&gt;--strictFunctionTypes&lt;/code&gt; and &lt;code&gt;--strictPropertyInitialization&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What do they do? In general, enabling them results in more TypeScript compiler errors. This is good! More compiler errors mean more help from the compiler.&lt;/p&gt;

&lt;p&gt;Let's see how enabling &lt;code&gt;--strictNullChecks&lt;/code&gt; helps you identify a lie.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&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;John&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;12&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;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;The type of &lt;code&gt;getUser&lt;/code&gt; promises that it will always return a &lt;code&gt;User&lt;/code&gt;. However, as you can see in the implementation, it can also return an &lt;code&gt;undefined&lt;/code&gt; value!&lt;/p&gt;

&lt;p&gt;Fortunately, enabling  &lt;code&gt;--strictNullChecks&lt;/code&gt; results in a compiler error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type 'undefined' is not assignable to type 'User'.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;TypeScript compiler detected the lie. You can get rid of the error by telling the truth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;strong&gt;Embrace type checking strictness. Let the compiler watch your steps.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stay up to date
&lt;/h2&gt;

&lt;p&gt;TypeScript language is being developed at a very fast pace. There is a new release every two months. Each release brings in significant language improvements and new features.&lt;/p&gt;

&lt;p&gt;It is often the case that new language features allow for more precise types and stricter type checking.&lt;/p&gt;

&lt;p&gt;For example, version 2.0 introduced Discriminated Union Types (which I mentioned in &lt;em&gt;Be precise&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Version 3.2 introduced &lt;code&gt;--strictBindCallApply&lt;/code&gt; compiler option which enables correct typing of &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;call&lt;/code&gt; and &lt;code&gt;apply&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codewithstyle.info/TypeScript-3-4-hidden-gem-propagated-generic-type-arguments/"&gt;Version 3.4 improved type inference in higher order functions&lt;/a&gt;, making it easier to use precise type when writing code in functional style.&lt;/p&gt;

&lt;p&gt;My point here is that it really pays off to be familiar with language features introduced in the latest releases of TypeScript. They can often help you adhere to the other four commandments from this list.&lt;/p&gt;

&lt;p&gt;A good starting point is &lt;a href="https://github.com/Microsoft/TypeScript/wiki/Roadmap"&gt;the official TypeScript roadmap&lt;/a&gt;. It's also a good idea to check out &lt;a href="https://devblogs.microsoft.com/typescript/"&gt;TypeScript section of the Microsoft Devblog&lt;/a&gt; regularly as all release announcements are made there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay up to date with new language features and make the work for you.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope you find the list useful. Like anything in life, these commandments shouldn't be followed blindly. However, I firmly believe those rules will make you a better TypeScript programmer.&lt;/p&gt;

&lt;p&gt;I'd love to hear your thoughts about it in the comments section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my course!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.educative.io/courses/advanced-typescript-masterclass"&gt;⭐️ Advanced TypeScript Masterclass ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>The meaning of union and intersection types</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Tue, 09 Jul 2019 19:17:23 +0000</pubDate>
      <link>https://dev.to/miloszpp/the-meaning-of-union-and-intersection-types-hk1</link>
      <guid>https://dev.to/miloszpp/the-meaning-of-union-and-intersection-types-hk1</guid>
      <description>&lt;p&gt;Union types are fairly popular in TypeScript. You might have already used them multiple times. Intersection types are slightly less common. They seem to cause a little bit more confusion.&lt;/p&gt;

&lt;p&gt;Did you ever wonder where do those names come from? While you might have some intuition about what a union of two types is, the intersection is usually not understood well.&lt;/p&gt;

&lt;p&gt;After reading this article, you will have a better understanding of those types which will make you more confident when using them in your codebases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple union types
&lt;/h2&gt;

&lt;p&gt;Union type is very often used with either &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&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;sayHello&lt;/span&gt; &lt;span class="o"&gt;=&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="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, the type of &lt;code&gt;name&lt;/code&gt; here is &lt;code&gt;string | undefined&lt;/code&gt; which means that either a &lt;code&gt;string&lt;/code&gt; OR an &lt;code&gt;undefined&lt;/code&gt; value can be passed to &lt;code&gt;sayHello&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="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;milosz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the example, you can intuit that a union of types &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; is a type that accepts both &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Union and intersection of object types
&lt;/h2&gt;

&lt;p&gt;This intuition also works for complex types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;foo&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;xyz&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;bar&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;xyz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sayHello&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;Foo&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Bar&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="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xyz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xyz&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;&lt;code&gt;Foo | Bar&lt;/code&gt; is a type that has either all required properties of &lt;code&gt;Foo&lt;/code&gt; OR all required properties of &lt;code&gt;Bar&lt;/code&gt;. Inside &lt;code&gt;sayHello&lt;/code&gt; it's only possible to access &lt;code&gt;obj.xyz&lt;/code&gt; because it's the only property that is included in both types.&lt;/p&gt;

&lt;p&gt;What about the intersection of &lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt;, though?&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;sayHello&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;Foo&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Bar&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="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xyz&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 &lt;code&gt;sayHello&lt;/code&gt; requires the argument to have both &lt;code&gt;foo&lt;/code&gt; AND &lt;code&gt;bar&lt;/code&gt; properties. Inside &lt;code&gt;sayHello&lt;/code&gt; it's possible to access both &lt;code&gt;obj.foo&lt;/code&gt;, &lt;code&gt;obj.bar&lt;/code&gt; and &lt;code&gt;obj.xyz&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hmm, but what does it have to &lt;em&gt;intersection&lt;/em&gt;? One could argue that since &lt;code&gt;obj&lt;/code&gt; has properties of both &lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt;, it sounds more like a union of properties, not intersection. Similarly, a union of two object types gives you a type that only has the intersection of properties of constituent types.&lt;/p&gt;

&lt;p&gt;It sounds confusing. I even stumbled upon a &lt;a href="https://github.com/Microsoft/TypeScript/issues/18383"&gt;GitHub issue&lt;/a&gt; in TypeScript repository ranting about naming of these types. To understand the naming better we need to look at types from a different perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set theory
&lt;/h2&gt;

&lt;p&gt;Do you remember a concept called &lt;em&gt;sets&lt;/em&gt; from math classes? In mathematics, a set is a collection of objects (for example numbers). For example, &lt;code&gt;{1, 2, 7}&lt;/code&gt; is a set. All positive numbers can also form a set (an infinite one).&lt;/p&gt;

&lt;p&gt;Sets can be added together (a &lt;strong&gt;union&lt;/strong&gt;). A union of &lt;code&gt;{1, 2}&lt;/code&gt; and &lt;code&gt;{4, 5}&lt;/code&gt; is &lt;code&gt;{1, 2, 4, 5}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sets can also be intersected. &lt;strong&gt;Intersection&lt;/strong&gt; of two sets is a set that only contains those numbers that are present in both sets. So, an intersection of &lt;code&gt;{1, 2, 3}&lt;/code&gt; and &lt;code&gt;{3, 4, 5}&lt;/code&gt; is &lt;code&gt;{3}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's imagine two sets: &lt;code&gt;Squares&lt;/code&gt; and &lt;code&gt;RedThings&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The union of &lt;code&gt;Squares&lt;/code&gt; and &lt;code&gt;RedThings&lt;/code&gt; is a set that contains both squares and red things.&lt;/p&gt;

&lt;p&gt;However, the intersection of &lt;code&gt;Squares&lt;/code&gt; and &lt;code&gt;RedThings&lt;/code&gt; is a set that only contains &lt;strong&gt;red squares&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L8aGCZiU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tpbziuorp9smrysig3kw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L8aGCZiU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tpbziuorp9smrysig3kw.png" alt="Intersection of sets" width="880" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Relationship between types and sets
&lt;/h2&gt;

&lt;p&gt;Computer science and mathematics overlap in many places. One of such places is type systems.&lt;/p&gt;

&lt;p&gt;A type, when looked at from a mathematical perspective, is a &lt;strong&gt;set of all possible values of that type&lt;/strong&gt;. For example the &lt;code&gt;string&lt;/code&gt; type is a set of all possible strings: &lt;code&gt;{'a', 'b', 'ab', ...}&lt;/code&gt;. Of course, it's an infinite set.&lt;/p&gt;

&lt;p&gt;Similarly, &lt;code&gt;number&lt;/code&gt; type is a set of all possible numbers: &lt;code&gt;{1, 2, 3, 4, ...}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Type &lt;code&gt;undefined&lt;/code&gt; is a set that only contains a single value: &lt;code&gt;{ undefined }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What about object types (such as interfaces)? Type &lt;code&gt;Foo&lt;/code&gt; is a &lt;strong&gt;set of all object that contain &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt; properties&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding union and intersection types
&lt;/h2&gt;

&lt;p&gt;Armed with this knowledge, you're now ready to understand the meaning of union and intersection types.&lt;/p&gt;

&lt;p&gt;Union type &lt;code&gt;A | B&lt;/code&gt; represents a set that is a union of the set of values associated with type &lt;code&gt;A&lt;/code&gt; and the set of values associated with type &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Intersection type &lt;code&gt;A &amp;amp; B&lt;/code&gt; represents a set that is an intersection of the set of values associated with type &lt;code&gt;A&lt;/code&gt; and the set of values associated with type &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, &lt;code&gt;Foo | Bar&lt;/code&gt; represents &lt;strong&gt;a union&lt;/strong&gt; of the set of objects having &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt; properties and the set of objects having &lt;code&gt;bar&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt;. Objects belonging to such set all have &lt;code&gt;xyz&lt;/code&gt; property. Some of them have &lt;code&gt;foo&lt;/code&gt; property and the others have &lt;code&gt;bar&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Foo &amp;amp; Bar&lt;/code&gt; represents &lt;strong&gt;an intersection&lt;/strong&gt; of the set of objects having &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt; properties and the set of objects having &lt;code&gt;bar&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt;. In other words, the set contains objects that belong to sets represented by both &lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt;. Only objects that have all three properties (&lt;code&gt;foo&lt;/code&gt;, &lt;code&gt;bar&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt;) belong to the intersection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world example of intersection type
&lt;/h2&gt;

&lt;p&gt;Union types are quite widespread so let's focus on an example of an intersection type.&lt;/p&gt;

&lt;p&gt;In React, when you declare a class component, you can parameterise it with thy type of its properties:&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;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the class, you can access the properies via &lt;code&gt;this.props&lt;/code&gt;. However, the type of &lt;code&gt;this.props&lt;/code&gt; is not simply &lt;code&gt;CounterProps&lt;/code&gt;, but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Readonly&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CounterProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;Readonly&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason for this is that React components can accept children elements:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;Counter&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;The children element tree is accessible to the component via &lt;code&gt;children&lt;/code&gt; prop. The type of &lt;code&gt;this.props&lt;/code&gt; reflects that. It's an intersection of (readonly) &lt;code&gt;CounterProps&lt;/code&gt; and a (readonly) object type with an optional &lt;code&gt;children&lt;/code&gt; property. &lt;/p&gt;

&lt;p&gt;In terms of sets, it's an intersecion of the set of objects that have properties as defined in &lt;code&gt;CounterProps&lt;/code&gt; and the set of objects that have optional &lt;code&gt;children&lt;/code&gt; property. The result is a set of objects that have both all properties of &lt;code&gt;CounterProps&lt;/code&gt; and the optional &lt;code&gt;children&lt;/code&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;That's it! I hope this article helps you wrap your head around union and intersection types. As it's often the case in computer science, understanding the fundamentals makes you better at grasping programming concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my course!&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my book!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typescriptmasterclass.com"&gt;⭐️ Advanced TypeScript ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>union</category>
      <category>intersection</category>
    </item>
    <item>
      <title>Comprehensive list of built-in utility types in TypeScript</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Sun, 30 Jun 2019 10:05:47 +0000</pubDate>
      <link>https://dev.to/miloszpp/comprehensive-list-of-built-in-utility-types-in-typescript-c8p</link>
      <guid>https://dev.to/miloszpp/comprehensive-list-of-built-in-utility-types-in-typescript-c8p</guid>
      <description>&lt;p&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html"&gt;Advanced types&lt;/a&gt; section of TypeScript docs mentions some very useful built-in types as examples of conditional types and mapped types. &lt;/p&gt;

&lt;p&gt;I was surprised to learn that there are more such types and some of them seem to be undocumented. This article contains a list of all such types.&lt;/p&gt;

&lt;p&gt;The list is based on what I could find in &lt;code&gt;es5.d.ts&lt;/code&gt; on &lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  List of types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Partial&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Partial&amp;lt;T&amp;gt;&lt;/code&gt; returns a type that has the same properties as &lt;code&gt;T&lt;/code&gt; but all of them are optional. This is mostly useful when &lt;code&gt;strictNullChecks&lt;/code&gt; flag is enabled.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Partial&lt;/code&gt; works on a single level - it doesn't affect nested objects.&lt;/p&gt;

&lt;p&gt;A common use case for &lt;code&gt;Partial&lt;/code&gt; is when you need to type a function that lets you override default values of properties of some object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;defaultSettings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getSettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Settings&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;Settings&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;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultSettings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;custom&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;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;However, this technique is not 100% type-safe. As pointed out by &lt;a href="https://www.reddit.com/r/typescript/comments/b2xftx/comprehensive_list_of_builtin_utility_types_in/eiw15mm?utm_source=share&amp;amp;utm_medium=web2x"&gt;AngularBeginner&lt;/a&gt;, if &lt;code&gt;custom&lt;/code&gt; has a property that has been explicitly set to &lt;code&gt;undefined&lt;/code&gt;, the result will end up having this property undefined as well. Therefore, its type (&lt;code&gt;Settings&lt;/code&gt;) will be a lie.&lt;/p&gt;

&lt;p&gt;A more type-safe version of &lt;code&gt;getSettings&lt;/code&gt; would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getSettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Settings&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;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Settings&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="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultSettings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;custom&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;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1404"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Required&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Required&amp;lt;T&amp;gt;&lt;/code&gt; removes optionality from &lt;code&gt;T&lt;/code&gt;'s properties. Again, you'll most likely need it if you have &lt;code&gt;strictNullChecks&lt;/code&gt; enabled (which you should 😉).&lt;/p&gt;

&lt;p&gt;Similarly to &lt;code&gt;Required&lt;/code&gt;, &lt;code&gt;Partial&lt;/code&gt; works on the top level only.&lt;/p&gt;

&lt;p&gt;The example is somehow symmetrical to the previous one. Here, we accept an object that has some optional properties. Then, we apply default values when a property is not present. The result is an object with no optional properties - &lt;code&gt;Required&amp;lt;Settings&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;applySettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Settings&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;actualSettings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Settings&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&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="c1"&gt;// do something...&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://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1411"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Readonly&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This one you probably have heard of. &lt;code&gt;Readonly&amp;lt;T&amp;gt;&lt;/code&gt; returns a type that has the same properties as &lt;code&gt;T&lt;/code&gt; but they are all &lt;code&gt;readonly&lt;/code&gt;. It is extremally useful for functional programming because it lets you ensure immutability at compile time. An obvious example would be to use it for Redux state.&lt;/p&gt;

&lt;p&gt;Once again, &lt;code&gt;Readonly&lt;/code&gt; doesn't affect nested objects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1418"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Pick&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Pick&lt;/code&gt; lets you create a type that only has selected properties of another type.&lt;/p&gt;

&lt;p&gt;An example would be letting the caller override only a specific subset of some default properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;updateSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;overrides&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pick&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;width&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;height&lt;/span&gt;&lt;span class="dl"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultSettings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;overrides&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;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1425"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Record&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Record&lt;/code&gt; lets you define a dictionary with keys belonging to a specific type.&lt;/p&gt;

&lt;p&gt;JavaScript objects can be very naturally used as dictionaries. However, in TypeScript you usually work with objects using interfaces where the set of keys is predefined. You can work this around by writing something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;string&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&lt;/code&gt; lets you do this in a more concise way: &lt;code&gt;type Options = Record&amp;lt;string, string&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1432"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Exclude&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Exclude&lt;/code&gt; makes a lot of sense when you look at types in terms of sets of possible values. For example, &lt;code&gt;number&lt;/code&gt; type can be looked at as a set containing all numerical numbers. &lt;code&gt;A | B&lt;/code&gt; is called a union because its set of possible values is a sum of possible values of &lt;code&gt;A&lt;/code&gt; and possible values of &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Exclude&amp;lt;T, U&amp;gt;&lt;/code&gt; returns a type whose set of values is the same as the set of values of type &lt;code&gt;T&lt;/code&gt; but with all &lt;code&gt;U&lt;/code&gt; values removed. It is a bit like substruction, but defined on sets.&lt;/p&gt;

&lt;p&gt;A good example of using &lt;code&gt;Exclude&lt;/code&gt; is to define &lt;code&gt;Omit&lt;/code&gt;. &lt;code&gt;Omit&lt;/code&gt; takes a type and its key and returns a type without this key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Settings&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="nx"&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="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SizeSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// type SizeSettings = {&lt;/span&gt;
&lt;span class="c1"&gt;//   width: number;&lt;/span&gt;
&lt;span class="c1"&gt;//   height: number;&lt;/span&gt;
&lt;span class="c1"&gt;// }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Omit&amp;lt;T, K&amp;gt;&lt;/code&gt; can be defined by picking all keys from &lt;code&gt;T&lt;/code&gt; except &lt;code&gt;K&lt;/code&gt;. First, we'll &lt;code&gt;Exclude&lt;/code&gt; &lt;code&gt;K&lt;/code&gt; from the set of keys of &lt;code&gt;T&lt;/code&gt;. Next, we will use this set of keys to &lt;code&gt;Pick&lt;/code&gt; from &lt;code&gt;T&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Omit&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="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="nx"&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Pick&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="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;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://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1439"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Extract&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Extract&amp;lt;T, U&amp;gt;&lt;/code&gt; return those types included in &lt;code&gt;T&lt;/code&gt; that are assignable to &lt;code&gt;U&lt;/code&gt;. You can say that it returns a &lt;em&gt;common part&lt;/em&gt; of &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;U&lt;/code&gt;. However, the types don't have to be exactly the same - it suffices that a type from &lt;code&gt;T&lt;/code&gt; is assignable to &lt;code&gt;U&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, you can use &lt;code&gt;Extract&lt;/code&gt; to filter out function types from a union type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Functions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// () =&amp;gt; void&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1444"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;NonNullable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;NonNullable&amp;lt;T&amp;gt;&lt;/code&gt; removes &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; from the set of possible values of &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is mostly useful when working with &lt;code&gt;strictNullChecks&lt;/code&gt; and optional properties and arguments. It has no effect on a type that is already not nullable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NonNullable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can find a good usage example of &lt;code&gt;NonNullable&lt;/code&gt; in my &lt;a href="https://codewithstyle.info/Deep-property-access-in-TypeScript/"&gt;previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1449"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Parameters&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This useful type returns a tuple of types of parameters of given function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FetchDataParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [number, string]&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;IdType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;FetchDataParams&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One interesting usage is typing wrapper functions without having to repeat the parameter list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchDataLogged&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="o"&gt;&amp;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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calling fetchData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;params&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;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1454"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ConstructorParameters&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ConstructorParameters&lt;/code&gt; is exactly the same as &lt;code&gt;Parameters&lt;/code&gt; but works with constructor functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;Foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FooConstructorParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ConstructorParameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="o"&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;One caveat is that you have to remember about &lt;code&gt;typeof&lt;/code&gt; in front of the class name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1459"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ReturnType&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The name is pretty self-explanatory - it returns a type returned by given function. I found this type really useful.&lt;/p&gt;

&lt;p&gt;One example is in Redux where you define action creators and reducers. A reducer accepts a state object and an action object. You can use &lt;code&gt;ReturnType&lt;/code&gt; of the action creator to type the action object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchDataSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetchDataSuccess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reduceFetchDataSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;fetchDataSuccess&lt;/span&gt;&lt;span class="o"&gt;&amp;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;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1464"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;InstanceType&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;InstanceType&lt;/code&gt; is an interesting one. You can say that it is complimentary to &lt;code&gt;typeof&lt;/code&gt; operator. &lt;/p&gt;

&lt;p&gt;It accepts a type of a constructor function and returns an instance type of this function.&lt;/p&gt;

&lt;p&gt;In TypeScript, &lt;code&gt;class C&lt;/code&gt; defines two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a constructor function &lt;code&gt;C&lt;/code&gt; for creating new instances of class &lt;code&gt;C&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;an interface for objects of class &lt;code&gt;C&lt;/code&gt; - the &lt;em&gt;instance type&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;typeof C&lt;/code&gt; returns the type of the constructor function.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;InstanceType&amp;lt;typeof C&amp;gt;&lt;/code&gt; takes the constructor function and returns type of the instances produced by this function: &lt;code&gt;C&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;C&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;InstanceType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// C&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/Microsoft/TypeScript/blob/4ff71ecb98ccbd882feb1738b0c6f1cc93c2ea66/src/lib/es5.d.ts#L1469"&gt;See implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my course!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.educative.io/courses/advanced-typescript-masterclass"&gt;⭐️ Advanced TypeScript Masterclass ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>advancedtypes</category>
    </item>
    <item>
      <title>Precise domain modeling with discriminated unions in TypeScript</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Tue, 27 Nov 2018 20:41:00 +0000</pubDate>
      <link>https://dev.to/miloszpp/precise-domain-modeling-with-discriminated-unions-in-typescript-3c8p</link>
      <guid>https://dev.to/miloszpp/precise-domain-modeling-with-discriminated-unions-in-typescript-3c8p</guid>
      <description>&lt;p&gt;In this post, we're going to look into an interesting feature of the TypeScript language. It's called &lt;strong&gt;discriminated unions&lt;/strong&gt; and is also known as &lt;strong&gt;algebraic data types&lt;/strong&gt;. The latter name comes from Functional Programming paradigm where such types are used very heavily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues with enum types
&lt;/h2&gt;

&lt;p&gt;Let me start by showing you an example of a problem that can be solved with discriminated unions. &lt;/p&gt;

&lt;p&gt;You're working on an application which deals with the management of customers. There are two kinds of customers: individual and institutional. For each customer kind, you store different details: individual customers have a first and last name and a social security number. Companies have a company name and a tax identifier.&lt;/p&gt;

&lt;p&gt;You could model the above situation with the following types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;CustomerType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Individual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Institution&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CustomerType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;firstName&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;lastName&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;socialSecurityNumber&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;companyName&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;companyTaxId&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, you have to make most of the fields optional. If you didn't, you would have to fill in all of the fields when creating an instance of &lt;code&gt;Customer&lt;/code&gt;. However, you don't want to fill &lt;code&gt;companyTaxId&lt;/code&gt; when creating an &lt;code&gt;Individual&lt;/code&gt; customer.&lt;/p&gt;

&lt;p&gt;The problem with this solution is that it's now possible to create instances that don't make any sense in terms of business domain. For example, you can create an object with too little info:&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;customer1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CustomerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Individual&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...or one that has too much data provided:&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;customer2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CustomerType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Individual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;companyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;companyTaxId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9243546&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wouldn't it be nice if the type system could help us prevent such situations? Actually, this is what TypeScript is supposed to do, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Discriminated unions to the rescue
&lt;/h2&gt;

&lt;p&gt;With discriminated unions, you can model your domain with more precision. They are kind of like enum types but can hold additional data as well. Therefore, you can enforce that a specific customer type must have an exact set of fields. Let's see it in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IndividualCustomerType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;individual&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;firstName&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;lastName&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;socialSecurityNumber&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;InstitutionCustomerType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;institutional&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;companyName&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;companyTaxId&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;CustomerType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;IndividualCustomerType&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;InstitutionCustomerType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CustomerType&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;We've defined two interfaces. Both of them have a &lt;code&gt;kind&lt;/code&gt; property which is a &lt;strong&gt;literal type&lt;/strong&gt;. Variable of literal type can only hold a single, specific value. Each interface contains only fields that are relevant to the given type of customer. &lt;/p&gt;

&lt;p&gt;Finally, we've defined &lt;code&gt;CustomerType&lt;/code&gt; as a union of these two interfaces. Because they both have the &lt;code&gt;kind&lt;/code&gt; field TypeScript recognizes them as discriminated union types and makes working with them easier.&lt;/p&gt;

&lt;p&gt;The biggest gain is that it's now impossible to create &lt;em&gt;illegal&lt;/em&gt; instances of &lt;code&gt;Customer&lt;/code&gt;. For example, both of the following objects are fine:&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;customer1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&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="s2"&gt;individual&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;socialSecurityNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;423435&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;customer2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&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="s2"&gt;institutional&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;companyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;companyTaxId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;124345454&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;...but TypeScript would fail to compile this 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="c1"&gt;// fails to compile&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customer3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;acquisitionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&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="s2"&gt;institutional&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;companyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;companyTaxId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;124345454&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;h2&gt;
  
  
  Working with discriminated unions
&lt;/h2&gt;

&lt;p&gt;Let's now see how to implement a function that takes a &lt;code&gt;Customer&lt;/code&gt; object and prints the customer's name based on their 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;function&lt;/span&gt; &lt;span class="nx"&gt;printName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;individual&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;institutional&lt;/span&gt;&lt;span class="dl"&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;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;companyName&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;As we can see, TypeScript is clever enough to know that inside &lt;code&gt;case "individual"&lt;/code&gt; branch of the &lt;code&gt;switch&lt;/code&gt; statement &lt;code&gt;customer.type&lt;/code&gt; is actually an instance of &lt;code&gt;IndividualCustomerType&lt;/code&gt;. For example, trying to access &lt;code&gt;companyName&lt;/code&gt; field inside this branch would result in a compilation error. We would get the same behaviour inside an &lt;code&gt;if&lt;/code&gt; statement branch.&lt;/p&gt;

&lt;p&gt;There is one more interesting mechanism called exhaustiveness checking. TypeScript is able to figure out that we have not covered all of the possible customer types! Of course, it would seem much more useful if we had tens of them and not just two.&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;// fails to compile&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;printName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;individual&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// case "institutional": return customer.type.companyName;&lt;/span&gt;
        &lt;span class="nl"&gt;default&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;exhaustiveCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&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;This solution makes use of the &lt;code&gt;never&lt;/code&gt; type. Since &lt;code&gt;case "institutional"&lt;/code&gt; is not defined, control falls through to the &lt;code&gt;default&lt;/code&gt; branch in which &lt;code&gt;customer.type&lt;/code&gt; is inferred to be of type &lt;code&gt;InstitutionCustomerType&lt;/code&gt; while being assigned to &lt;code&gt;never&lt;/code&gt; type which of course results in an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Discriminated union types are pretty cool. As I mentioned, the whole point of TypeScript is to help us catch mistakes that we would make without having type checking. Discriminated unions help us model the domain in more detail, therefore making &lt;em&gt;illegal&lt;/em&gt; instances impossible to create.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;One could argue that the same thing could be achieved with inheritance (or interface extension in this case). And that's true. Solving this with inheritance would be an Object Oriented Programming approach while discriminated unions are specific to Functional Programming. I think this approach makes more sense in the context of web applications where we often fetch data from some REST API which doesn't support object inheritance. What's more, exhaustiveness checking is not possible to achieve with object inheritance. &lt;/p&gt;

&lt;p&gt;It's an example of the classical &lt;em&gt;composition versus inheritance&lt;/em&gt; dilemma.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn more?
&lt;/h2&gt;

&lt;p&gt;Did you like this TypeScript article? I bet you'll also like my book!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typescriptmasterclass.com"&gt;⭐️ Advanced TypeScript ⭐️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>union</category>
      <category>types</category>
    </item>
    <item>
      <title>Becoming a tech public speaker: lessons learned</title>
      <dc:creator>Milosz Piechocki</dc:creator>
      <pubDate>Sun, 25 Nov 2018 09:38:04 +0000</pubDate>
      <link>https://dev.to/miloszpp/becoming-a-tech-public-speaker-lessons-learned-18la</link>
      <guid>https://dev.to/miloszpp/becoming-a-tech-public-speaker-lessons-learned-18la</guid>
      <description>&lt;p&gt;&lt;strong&gt;This post has been originally published on &lt;a href="https://codewithstyle.info/becoming-tech-public-speaker-lessons-learned/"&gt;my blog&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The year is nearing its end, so I'd like to share some things I've learned on my speaker's journey.&lt;/p&gt;

&lt;p&gt;I've already written &lt;a href="https://codewithstyle.info/introverts-guide-public-speaking/"&gt;one article&lt;/a&gt; on this topic. Read it if you would like to know how (and why) to get into tech public speaking. This post will focus on advice for speakers who already have a little bit of experience.&lt;/p&gt;

&lt;p&gt;I made the decision to start speaking publicly almost two years ago - in February 2017. I began with meetups and slowly progressed towards my goal - an international conference - which I managed to achieve in September 2018. &lt;strong&gt;During these two years, I gave 11 talks in total&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can find the full list of my talks &lt;a href="http://miloszpiechocki.com/speaking.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Call For Papers
&lt;/h2&gt;

&lt;p&gt;Most importantly, you need to submit a lot. Of course, there are conferences where talks are chosen purely based on the abstract you provide. However, the majority will look at your speaking history, your presence in the web, etc. &lt;/p&gt;

&lt;p&gt;So unless you are a core contributor to a popular library or a published author, your chances of getting selected are relatively low (&lt;a href="http://www.papercall.io"&gt;PaperCall.io&lt;/a&gt; mentions 1 in 10 on average). Therefore, &lt;strong&gt;you need to apply to a lot of conferences&lt;/strong&gt; hoping to get selected for at least one.&lt;/p&gt;

&lt;p&gt;This takes time and effort, but it pays off. In 2018, I applied to almost 30 conferences and got selected to 5 of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topic and abstract
&lt;/h2&gt;

&lt;p&gt;Adjust the topic of your talk to the audience. It's a cliche, but it has some important consequences.&lt;/p&gt;

&lt;p&gt;Your topic doesn't have to be super advanced. When applying to general-purpose, multi-track conferences which don't focus on a specific technology, it's perfectly ok to submit an introductory level topic. One of my best-rated talks was an introduction to functional programming in JavaScript at a frontend track of &lt;a href="https://4developers.org.pl/"&gt;4 Developers 2018&lt;/a&gt; - a large, multi-tech conference. I think &lt;strong&gt;it's generally a good idea to begin with a less advanced topic&lt;/strong&gt; as such presentation will be easier to deliver.&lt;/p&gt;

&lt;p&gt;Conversely, your talk should be a bit more in-depth if you are going to present it at a specialist conference dedicated to a specific tech.&lt;/p&gt;

&lt;h2&gt;
  
  
  At the conference: before the talk
&lt;/h2&gt;

&lt;p&gt;Your day will be split into two parts: before and after your talk. The shorter the first part, the better - but it's usually something you don't have influence on. Anyway, I used to stress a lot before a talk, which made the first part of the day really unpleasant. However, with time and experience, the time before the talk becomes much less stressful.&lt;/p&gt;

&lt;p&gt;I know it's hard, but try not to give up to the stress. &lt;strong&gt;Talk to other speakers&lt;/strong&gt; - those more experienced are usually very friendly. The inexperienced are in the same situation as you, so sharing your anxiety will make it easier to bear. There is a chance that fellow speakers will be sitting in the audience during your talk. You will feel better knowing there is at least one friendly person in the audience. Shout out to &lt;a href="https://twitter.com/jawache"&gt;Assim Hussain&lt;/a&gt; who was really supportive and gave my talk a lot of visibility by twitting it live at &lt;a href="http://refresh.rocks/"&gt;Refresh Conference 2018&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Don't rehearse too much on the conference day. One run before leaving the hotel in the morning is enough. By this time, you should already have rehearsed enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  At the conference: after the talk
&lt;/h2&gt;

&lt;p&gt;Now you can enjoy the rest of the conference! Have some rest and relax a bit. If you still have some energy left, it's a good idea to &lt;strong&gt;approach some attendees and talk to them&lt;/strong&gt;. Ask them how do they like the conference in general. You don't have to directly ask about feedback regarding your talk. Most of the time, the topic will come up anyway. If it doesn't, it's still a great chance to learn the attendee's perspective and see what kind of talks do they like.&lt;/p&gt;

&lt;p&gt;BTW, I don't feel comfortable approaching strangers at all. However, it seems to be a learnable skill (same as not getting freaked out before your talk is). I find &lt;a href="https://kopywritingkourse.com/how-to-start-a-conversation/"&gt;this guide&lt;/a&gt; very helpful in dealing with this.&lt;/p&gt;

&lt;h2&gt;
  
  
  After the conference
&lt;/h2&gt;

&lt;p&gt;Wait a few days and &lt;strong&gt;send an email to the organizers asking about feedback&lt;/strong&gt; with regards to your talk. Most conferences provide some way of rating talks to the attendees.&lt;/p&gt;

&lt;p&gt;The feedback can be a great way to tell what needs improvement and how well did the topic match your audience. However, don't worry too much if you receive some negative, non-constructive remarks. There will always be some haters and it really doesn't mean anything when 2 out of 200 people didn't like your talk. &lt;/p&gt;

&lt;p&gt;Now you can decide whether you want to reuse your topic or come up with a new one. I think reusing the topic a few times is perfectly alright. However, I adjust and polish my talk before each conference - based on the feedback, target audience and desired talk duration. &lt;/p&gt;

&lt;h2&gt;
  
  
  Is it worth it?
&lt;/h2&gt;

&lt;p&gt;Totally! I've already mentioned some benefits of public speaking in the &lt;a href="https://codewithstyle.info/introverts-guide-public-speaking/"&gt;previous article on the topic&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It gets even better when you start going to conferences instead of meetups. When traveling abroad, you will often be reimbursed for the flight and a hotel. You get to meet some seriously experienced speakers and can get a lot of inspiration and advice from them. Most importantly, it's really rewarding and gives you a sense of achievement.&lt;/p&gt;

&lt;p&gt;So, if you're wondering whether you're ready for a conference talk - &lt;strong&gt;don't hesitate and start applying&lt;/strong&gt;! &lt;/p&gt;

</description>
      <category>speaking</category>
      <category>conferences</category>
      <category>tech</category>
    </item>
  </channel>
</rss>
