<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: typescript</title>
    <description>The latest articles on Forem by typescript (@typescript).</description>
    <link>https://forem.com/typescript</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%2Forganization%2Fprofile_image%2F2560%2Fa664849a-eb4e-411e-a928-c96a0af9868b.png</url>
      <title>Forem: typescript</title>
      <link>https://forem.com/typescript</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/typescript"/>
    <language>en</language>
    <item>
      <title>Type | Treat 2021 - Wrap-up</title>
      <dc:creator>Orta</dc:creator>
      <pubDate>Sat, 30 Oct 2021 14:31:39 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-2021-wrap-up-loo</link>
      <guid>https://forem.com/typescript/type-treat-2021-wrap-up-loo</guid>
      <description>&lt;h2&gt;
  
  
  Type | Treat Challenge Wrap-up
&lt;/h2&gt;

&lt;p&gt;That's all the challenges done! If you missed any of the challenges they're all available in &lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a"&gt;the Playground here&lt;/a&gt;. Let's talk through the final answers to day 5's challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;In this challenge we were working with an existing object literal which had been &lt;code&gt;as const&lt;/code&gt;d. The goal was to use &lt;code&gt;keyof&lt;/code&gt; and &lt;code&gt;typeof&lt;/code&gt; to extract interesting sets of strings from the object. The first being the keys in the object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- type SchemeNames = "background" | "textColor" | "highlightOne"
&lt;/span&gt;&lt;span class="gi"&gt;+ type SchemaNames = keyof typeof scheme
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Idealy you might have noticed the 'key of' in the comment, which could have led you to &lt;code&gt;keyof&lt;/code&gt;, from there you needed to re-use &lt;code&gt;typeof&lt;/code&gt; to extract the type from &lt;code&gt;scheme&lt;/code&gt;. This gets all of the keys from that constant.&lt;/p&gt;

&lt;p&gt;Next, we asked if you could improve&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;possibleSchemeItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&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="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;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, you can switch &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;SchemeNames&lt;/code&gt; - this example was made so that there was an interesting function to play around with. You could switch &lt;code&gt;colors&lt;/code&gt; to &lt;code&gt;typeof schema&lt;/code&gt; but nothing you do around &lt;code&gt;Object.keys&lt;/code&gt; would keep the types retained. This is kind of interesting, the reasoning is that TypeScript cannot make &lt;em&gt;reasonable&lt;/em&gt; guarantees that the return value of &lt;code&gt;Object.keys&lt;/code&gt; actually &lt;em&gt;is&lt;/em&gt; &lt;code&gt;keyof typeof colors&lt;/code&gt; (because of JavaScript prototype chaining) and so you have to re-type that line. Interesting.&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;possibleSchemeItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;scheme&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;SchemaNames&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&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;SchemaNames&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;keys&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we had you figure out how to get the values of &lt;code&gt;schema&lt;/code&gt; as a union:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- type PossibleColors = '#242424' | '#ffa52d' | '#cafe37'
&lt;/span&gt;&lt;span class="gi"&gt;+ type PossibleColors = typeof scheme[SchemaNames]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We tried to be quite explicit in the clue leading up to this one, because jumping to an indexed type might not be instinctive for beginners. This we considered to be the trickiest part of the challenge.&lt;/p&gt;

&lt;p&gt;Then to wrap up the challenge, and to make sure the types you are creating are constructive in a real world-ish scenario, we presented a &lt;code&gt;Record&lt;/code&gt; to see if you knew that the first parameter can be a list of keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- type Scheme = Record&amp;lt;string, string&amp;gt;;
&lt;/span&gt;&lt;span class="gi"&gt;+ type Scheme = Record&amp;lt;SchemaNames, string&amp;gt;;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which would cause a compiler error with &lt;code&gt;previousScheme&lt;/code&gt; - letting you know it worked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEDEHsCdQFwBYFNQAkCGAbTkDuSkA7UfJAayIBMAaUAT0gFcByANxUqQGMBLTy+JFBcE6QgHMUiJACgQoAM5I4oSADNhkHNAWg1Mek1gNGsfACMFPOFKHmUCgA6RIZOvGQBbJJRlywAOoIPJgoJszQKMiRtCagnuju6Lr42KDoXCqYPBTpoOIuAgpcTHD+6YQCPJ6O0JDsHiglnObJKLjBoYYskaDRSABcfiWECirFXigAvKAA3jKgi6CtXGTidYyVA6DMAMQATAAsR0fM1AtLNgAecADCWjDbe2pq6ACs+5RnF4vB4gjZf5wADyhEGO12XHQaiQAGYAOzfJZ9Hj-QEIOAAFVwkCeuwAnEh9gAGF7MGQAX3SuhGYz88gAklkXGRdNlciZYHA6I52sERKBIrUkEpCHBdFhMKBnAorOYuuUStpdDxdKVVBpKOgbLQocQ4iIxJIPKr4DzbKByvZhJFtT5QJQeJFMph3Go6p5GqAKHQ1RoAAYTJDef3pcz1JAAfj83N5oAAyiJg+gAHLoby6GY+9Rm3k5oPeelgJmgHCuNk5KT9Zi6RCmxhKNSMKVNwiZHiQYj+mVy0KJyZM4MKf3lDo8AU45sCSJwUzEaSgQjpkUar1Koy6cyMFTWQXKOcS8pjaA8CQS6DQRIAOlAtzE3VA1VqEZNCmjMlb7c70sgsp48qQftgyQQdPAUAAKdcdG2MQ6AASm2ICEjTDMAG0AF05h+TRRhUH1M1AYFzAAK24OAr3wyCHh0ODqQTJNkOXBQMOwmc529JBfUpItQAATSYRRnDgGwBDESBpFgKElFXe9Si1ETFDgE8JFATYO0IXUxHKA1QnvOtdEYRxBGWdwyzIU9xHSFQF1jFB8wY9AKl8eRpGIU9OCuCzVGs5Afz-ADFAcxcmPfFzzVAAAFX9eyQe5lVAGY9hOY5DmYUAAB8IRed5PjSzK9ihGEEXJWzIui-9QjimACNs+zJlQ7MNFqjQCyQdC-HKFM8A8bVujYJpdLBARDMaaTbIUWIBNwMRrKEBIKCPUwq16iSkBrPISkcdwcwXGBUVPLBAsmRSQildANkqK9yjvfUBPmhwlp6nyUG7SJWA7BskKQUN7BwXATrSUQFHKBcFGXDjfTohdAwY77VKM9Bw3Yd9Sq+hLQAAJW4GBKAAHiQ1MmNoY8LIAPgAbmGTsxmlN6PoUL7ENh9H5mRFY1guyg8QARl5vmkUuJAbiq6A8S4AA2YkAA5iWJAXflRAFFZBME8Vl8XWm574KXJoA"&gt;Our answer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;For this challenge, we started with the type we wanted you to write, and then tried to find incremental steps which built up in complexity till you hit it.&lt;/p&gt;

&lt;p&gt;The total change we were looking for was this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleSale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Books&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To:&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;handleSale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;events&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;Book&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Books&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s2"&gt;`on&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;genre&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Book&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;Getting there is a bit of a jump!&lt;/p&gt;

&lt;p&gt;We first asked you to switch the &lt;code&gt;string&lt;/code&gt; in the &lt;code&gt;Record&lt;/code&gt; to be &lt;code&gt;Books&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- function handleSale(events: Record&amp;lt;string, (e: Books) =&amp;gt; void&amp;gt;) {
&lt;/span&gt;&lt;span class="gi"&gt;+ function handleSale(events: Record&amp;lt;keyof IncomingBookMap, (e: Books) =&amp;gt; void&amp;gt;) {
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step was to remove the &lt;code&gt;Record&lt;/code&gt; and replace it with its underlaying mapped type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- function handleSale(events: Record&amp;lt;string, (e: Books) =&amp;gt; void&amp;gt;) {
&lt;/span&gt;&lt;span class="gi"&gt;+ function handleSale(events: { [Book in keyof IncomingBookMap]?: (e: Books) =&amp;gt; void }) {
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;?&lt;/code&gt; being the key that if you searched the TypeScript documentation for &lt;a href="https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#mapping-modifiers"&gt;"mapping modifier"&lt;/a&gt; you'd see the documentation around &lt;a href="https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#mapping-modifiers"&gt;mapped types&lt;/a&gt; which we also improved in the process of making this challenge.&lt;/p&gt;

&lt;p&gt;We thought that could be enough for some folk, and that was a good pausing point and thus classed the final change as a bonus. That jump revolved around using key remapping via &lt;code&gt;as&lt;/code&gt; in the mapped type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- function handleSale(events: { [Book in keyof IncomingBookMap]?: (e: Books) =&amp;gt; void }) {
+ function handleSale(events: { [Book in Books as `on${Book["genre"]}`]?: (e: Book) =&amp;gt; void }) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;IncomingBookMap&lt;/code&gt; existed specifically to add the prefix &lt;code&gt;on&lt;/code&gt; to the genre of each book, which is handled by template string literals. All of the documentation for these concepts are in the same page, so after a few reads it should hopefully all make sense.&lt;/p&gt;

&lt;p&gt;This system is &lt;em&gt;more or less&lt;/em&gt; how the DOM's event system works, and is what the idea is loosely based on, &lt;a href="https://github.com/microsoft/TypeScript-DOM-lib-generator/blob/008041c9638d034fc2cb366994c9bd79a43fac36/baselines/dom.generated.d.ts#L4549-L4563"&gt;from &lt;code&gt;lib.dom.d.ts&lt;/code&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DocumentAndElementEventHandlersEventMap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;copy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ClipboardEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cut&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ClipboardEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paste&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ClipboardEvent&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;DocumentAndElementEventHandlers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;DocumentAndElementEventHandlersEventMap&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DocumentAndElementEventHandlers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DocumentAndElementEventHandlersEventMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;AddEventListenerOptions&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Roughly translates to english as "DocumentAndElementEventHandlersEventMap" shows how to handle &lt;code&gt;document.addEventListener("copy", (evt) =&amp;gt; { ... })&lt;/code&gt; and what to map the first argument of that function to. The DOM types can't really switch to use a template literal because not all properties have an &lt;code&gt;on&lt;/code&gt; prefix, but it's a pretty logical expansion of the idea in specific cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHICcCmp7QHZoJZoOagIagBGkkA1gM4AWkADgDQFoAmoz082eAEvgDZ9IAd0SI0oAJ4wAUCFBV8AN2SEKtRAGNM-UADNI8eQfgHipSsXwVErSOJpDQAW3xoJoHDQoAXCrLDeVIhIBCHYoIHIJOQAdNLS2N7BuvgayABC5qAA3h5iSABcoD6cuIz4tLR8EgAimBQaMGjeRQAUzPWN6C2gaNBORMEAlKAAvAB8oIqQmKygAL4A3PFyAGKmFJhOVZha3hKMIrACBBQU-ciRIfghdtURQpB5aEgUjETQ3v6gs4j890dWHxMGRLk98MxWFZnK53NDaJAzpgiHxkHx8ElDMxhOJIqBgWhEHEEs1kqlkNxjAZMuRQIgAB5JFgUUA0sg5Z6FUAAIho8BM8G5jE8iO8AGEmj0+gNgoxFLtvFsKBLukVpYNDPMSZiUmlQAAlSAuNBpNl0xliZgss25HD5RBFbkmY1pIWgWgmbz4HB2ereABy+CcDuK3lKeC10n26lZ5hZo1AlP51KyAB8DUbXKbzMtvlBoKAhK5vBEngoWKiIkFivxkNBNrgmHTlM0ALQUCQ+RBOQ5UXZUfFx-Eg5CwOwAbTtL0QAF0xpNWtEyENYHE5AAVJ4uUGSGCGYG6ZB-Tay3cFhTKAgw2igSC6KtHlu+UsPzCGJcs7xPSJv5tiEtoEGDorAEEgxgAkiaRpcGyACyFRjDk3ygLeaB8gKRRJgKbLLHIKF2M6WYhoaLqIDh3yRnI+aGIgT7FJ2SROIO5AssCO6BPU7yfIWQTiFIBY+DcJZfgQGhpGcD4EJCmCKnYOi6JgiB8Fa3x2HSqQDlOITrmBiAAMoaJwtAloJ8DPiJOCYJewQChQMSgOuCjeLALJoJAJY4EgGIFPE5bMKiem1q02TSPhaFUvAi7mCMIUoShS4xBUVS1J0kpRbEIo+F0zSgAAVKAACsQyhQs9DSPMIwgYmwSIC5km6OgGiyeIQhBCE-HHHwxDINiXCSY88BkIwGiuGeoCNGgyhmVW9R6I1zUvn5lbfLQVgNnggQmNAniSY0-KaMJukvnie1IE1c0ms19kAOq1SEPp9SJYZwiwhYGOyakyT8JpIMGzT-AcxSQN82JoLAJaHkpw47vxvSiKwIkAFb9DeImEOo8CHudrgUCIhgSIg3jEg1l2YGpS36UFtH-hQRS5OOZrhGyLLQgABnYAAk2RsuO3JaYg3IzvMrMzgA-G0IZsiMExTDMrAVUhKFyLdCDIJgOBueGklbFU3b-hiZPiMwhP4JgfAsvohgcRb82G3EStgLBfxYGUkl3O4CJIiiyADeysOEjYL7Yj8LLhHirPU80FCs+6NxBgQJDKHEkb+GAelJDeACMVViqNsPbsgrMU4FqIxyTTWG6h9ypGkxmgOz4XJvAMeuKwDeESaiAtyyoKdqL8QD6noDp4gN4AExVf6whVhi9d2O5bUx7Np0Hfc8Cm+tTY2QYjCwyN4i-ZAl4ycScgAPK4k5xTQEQiMHcNecwDCO5F63AW1i3YmjyWdjIHekleS6uXBagw+r4CINYZootQDrBovSIMutGCcE8ABYQ3xYYXjBN9DQfBoDGzni8TMncY4fBLF9bEiBXILy4PZTc7poAnGtreXQ94Or3RmI2ESAcEZPG+AXIGwZ3RIG8PsC6zAgL-S6hocsdpPzfmrNGP+94I5PmjqcM8nU4aB0IC4SofUnCQA6ApYIp8wDrkwLQIoNQ7Dg1APWQuAAFIS2g+Bl1MNbYkg8h4jxvAAZlAJPaegRZ54mAYbFmIRrAlmgAwH4zlPxbCwX2YS1YXDhA9JAb2Tgih4kUX4OQltJKsyXEvNAmx8F-GkRdCualuFyO6pYawthL7IEAoI-+eJI5EwCXIXOfEn6rQksEshaBLYuAWptGAO1cm6X7l4kCYBMh9FpsPDOoAAAsATvh9MLMgQ+l48TcL0KYVmkFGhOBguYeCtAW6MMgHaK4SClISD6hQSAqJ7hqVZszGOIlDJ-CSJJPJ-cqIwE0UckS9iBGXG7FUDEyASj6NcBYhhBs1IiSEOvG8MTJL-jfMgMJdhiRAA"&gt;Our answer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thanks!
&lt;/h3&gt;

&lt;p&gt;There are a few people involved in getting &lt;code&gt;Types | Treat&lt;/code&gt; running whose name you don't see on the masthead: &lt;a href="https://twitter.com/NoWaySheCodes"&gt;Gabriella&lt;/a&gt; and &lt;a href="https://twitter.com/drosenwasser"&gt;Daniel&lt;/a&gt; on the TypeScript team, and the folks in the TypeScript Community Discord - especially &lt;a href="https://github.com/webstrand"&gt;webstrand&lt;/a&gt; and &lt;a href="https://twitter.com/M_Rutter"&gt;michael&lt;/a&gt;. My wife, &lt;a href="https://github.com/dangermcshane"&gt;Danger&lt;/a&gt;, should probably also get a shout for helping to provide themes - we've done 40 challenges so far and have to dig pretty deep occasionally to be fun and topical.&lt;/p&gt;

&lt;h4&gt;
  
  
  Feedback
&lt;/h4&gt;

&lt;p&gt;If you gave &lt;code&gt;Types | Treat&lt;/code&gt; a shot, we love for you to run through our &lt;a href="https://www.surveymonkey.com/r/FSQ7DLC"&gt;6 question survey&lt;/a&gt; which help us figure out how to change and improve. Feedback on Twitter is useful, but there's only so much context you can gve in 280 characters!&lt;/p&gt;

&lt;h3&gt;
  
  
  From here?
&lt;/h3&gt;

&lt;p&gt;If you've not done &lt;a href="https://www.typescriptlang.org/play/#gist/303ebff59a6fc37f88c86e86dbdeb0e8-0"&gt;the 2020 &lt;code&gt;Type | Treat&lt;/code&gt;&lt;/a&gt;, it's also good!&lt;/p&gt;

&lt;p&gt;If you want to challenge yourself further, check out &lt;a href="https://github.com/type-challenges/type-challenges#intro"&gt;types-challenges&lt;/a&gt; this clever system of type challenges goes all the way up to "very challenging for the TypeScript team" and also run entirely in the TypeScript Playgound. It's great work.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat 2021 - Day 5</title>
      <dc:creator>Orta</dc:creator>
      <pubDate>Fri, 29 Oct 2021 19:59:59 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-2021-day-5-1mlo</link>
      <guid>https://forem.com/typescript/type-treat-2021-day-5-1mlo</guid>
      <description>&lt;h2&gt;
  
  
  Type | Treat Challenge 5
&lt;/h2&gt;

&lt;p&gt;Welcome to the fifth, and last, &lt;code&gt;Type | Treat&lt;/code&gt; challenge! These challenges are a series of blog posts which have 2 code challenges in, one for beginners and one for intermediate TypeScript programmers. We're on day five, which means going over the answers from &lt;a href="https://devblogs.microsoft.com/typescript/type-treat-2021-day-4/"&gt;yesterday&lt;/a&gt; and have 2 new challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;This challenge aimed to be generics 101, first introducing the concept of making your function pass a type from the function to the argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-  function getBowl(items: any) {
&lt;/span&gt;&lt;span class="gi"&gt;+  function getBowl&amp;lt;T&amp;gt;(items: T) {
&lt;/span&gt;      return { items }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;any&lt;/code&gt; acted as hint clue about where to look, and this example is almost the first code sample on the &lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html"&gt;Generics chapter&lt;/a&gt; in the Handbook, so it felt like a good intro.&lt;/p&gt;

&lt;p&gt;The second part involved understanding &lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-constraints"&gt;generic constraints&lt;/a&gt;, these are essential tools in helping you define the baselines for types which can be used in your function. In this case we didn't provide the word "constraints" but opted for a more cryptic clue by setting up the function most of the way, then saying you only needed two words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-  function fillBowl&amp;lt;T&amp;gt;(candy: T) {
&lt;/span&gt;&lt;span class="gi"&gt;+  function fillBowl&amp;lt;T extends string&amp;gt;(candy: T) {
&lt;/span&gt;      return { candy }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By saying that &lt;code&gt;T&lt;/code&gt; extended &lt;code&gt;string&lt;/code&gt; then the string literals are correctly passed through the function - which removes all the compiler errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHIDcCmoDmkAuoCeMBOBnRAGwDNQAjaAOwGMALUSM8yAdyP0bJoEMqATLABoK0TOjrIW7Tj1zIAUCFAAraPkwAiFIiqJcASxqaKbDgDoIMULyqgADmNB8sEg1RSh3oCYgC2Inz8qIiYLm4eSmDkPDQA1oxOTD6SfpYKCiTUNOgGkHY66ABCZgA8ACoAfAAUBuj++ABcoOUAlKAA3gqgPaDy6NC4dh1e9X6cAL4KUwo0+Ro2kqxYALIGAB4l7KAAvCHFZtUjc0SQBM0A2pry-Joi2vK6d6Ca5ETQiJoAuiIauDyscj6QyIJovfCQPyfUATVpRXo9AB6AH4MnMqAtbPwDIh+ABBez2IigrZEXb7UlHHxYeygy6acp8FB0aDvZ6aFY8ADnAGPQPxIM4-Gd2eUmCREMgCUTQd8YXDlAjQCiMspynQDJxNc5QPg6DwoSIgbx1MgDPxEDwiEQsCltawYERgv9NcgeDZIfYDMTcM5cLgzo00UEcfjCcT8KTzHUGuZ0DTEBcAAxfVVgADCfGw1giCWS7tYPFt6EFxPEkgccgNoX0XFAAANCqT66A4pL7ClkPHaaB4cl6zHxi2JAHoMzO6AsrRcvlURl5wv4QBleyQb36ThA06sZyySu4TDJXygRDreoYvJ2I8azing0yxcL5RL3LWnXkOqTwa+X0kM4pSBCEYOwiDkHRdRoR4MUfeF00gSAiBEH8zUwTVF2UKA4CQVAMGzQZCFIURaAYZJpA4OssWEURyykMxZHkXtlDUBZtF0fQjBMMj8EsTDUH+cgdQlHcSD4GhbXIf4BFxUBGnQPxmi45wBHhEhvTJY9FNYOoGF8AxfUo8wMinHJL0nNTSQqE8z10fhOD+dwUBqSjmjaTpul6fpBmGGwgltKYZnRBY-DkSMzHJVTrUpTRgoITQ4UCzB8CoIw2wIUlwvMw5NCSlKNzi2Z5kSuI6nQCN0r2CKiCi-BivQUrZTheEAElxC8zgYHLHgwknRAd2K2y-WQL14mLOgYGZIR4SCYCbVAQsqHEQVCmArsEzrHyBFtEgAz8E9YgYMjDIKjFMBQAwkAAeTEJdkviDdyWqP5mmy27UvwOLdkqToYWOhYzsu67avqzg9ke9BcGemqSojD6di+kYpgS1BzsQK70E5NKQoep6Xhi972jh76ZjVG9QChPhOBwaA5rU0A9GkksrPPYJj3rSrmx8SB4X1ARiUrfB8AcnV8FpGgDFUmhdXBoWiBjf51LoUdx18eFj2MmcqB46wtLffJZvplnBR4fgWYdOazgGxnVYrdXTMZ4K2ztTgHVwOIjv+1HrtejdHu9tKzHMSi4Q9tGlyBiNHvDkkA6DhQQ7EDHIxC6o8ajWOMiAA"&gt;Our answer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;The intermediate challenge also invovled generic constraints, so if you had just finished the beginner's then you were in a good place to figure this challenge. The key is to make a&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- const check = (data: Competitor[]) =&amp;gt; {
&lt;/span&gt;&lt;span class="gi"&gt;+ const check = &amp;lt;Type extends Competitor&amp;gt; (data: Type[]) =&amp;gt; {
&lt;/span&gt;      return data.map(competitor =&amp;gt; {
          if (competitor.weight &amp;gt; 2121.5) throw new Error("Stop the show, world record hit!")
          return { ...competitor, judge: (...args: unknown[]) =&amp;gt; { } }
      })
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is testing a few different things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing generics with an arrow function&lt;/li&gt;
&lt;li&gt;Using an &lt;code&gt;extends&lt;/code&gt; constraint for the interface subtypes&lt;/li&gt;
&lt;li&gt;Re-using the type parameter inside the array&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We left a tricky problem with this challenge, but explicitly didn't call it out. The function &lt;code&gt;judge:  (...args: unknown[])&lt;/code&gt; is a types gap. There is no validating that the judge function actually works like expected. There are two approaches for handling this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- return { ...competitor, judge: (...args: unknown[]) =&amp;gt; { } }
&lt;/span&gt;&lt;span class="gi"&gt;+ return { ...competitor, judge: (...args: Array&amp;lt;T[keyof T]&amp;gt;) =&amp;gt; { } }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version &lt;a href="https://twitter.com/faridz974/status/1454107977267417089"&gt;from @faridz974&lt;/a&gt; would ensure that the right values were used in the function (e.g. you couldn't accidentally put in an object to something which could only accept &lt;code&gt;string&lt;/code&gt; and &lt;code&gt;number&lt;/code&gt;s) but it ignored the order. An accurate, but whole-heartedly not recommended for production version which does take order into account comes from converting an &lt;a href="https://github.com/Microsoft/TypeScript/issues/13298#issuecomment-707369176"&gt;interface to a tuple on GitHub&lt;/a&gt; which is a bit too long to print in here, but here's a &lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHICcCmoCWA7UBjAFgQ3gObKQBmo80aa6BoADtALZ0DW65uALjVpM4t26Q0AZwA0oAJ4xQeAG6IAUCFC5QJRAHdQnSOUqq0AEykxYC0ACtoIzqAKQ7nbMhEoAXskx86AlEIxNSHg2NAIAOkVFdE5EeBJcTGQAYR8-XXhQAG9FUDzQYAAqQtAASQwAGwAjEVBC4Fz8zUQUAmxOAC5QNCYquIBuRQBfKJi4hKTQAGUPRFT+QRRhUEQAD1jjWvnfQWDs0BHotFj4xOQAEURveC4UBW30pYw1jaMttN3MnPydF0ZELq2eA0YZRFQAFWwKFq3jQCngnFquAw+Cq-hu8EkoEgVUsV04AFosZxJL5UMc9GpONA6BVEOFQMowO1OHQRB0QAR-NhoFVwt5GMAALIoTDwSAiUicYDg0mIKZilB0aXQkTQRAiYAARgAzAAmACcAA4AMSq9UC-7HAkAdgADDadQA2A1am1OsFgKDQUCMVrtVQiFigTTYLFGSAanSWSwkOQobqOchXPhWkw2HjOaHk+jiozQTABAD8ntAkOQ4ugbXs0Ls2ecXF+yAA+sEjHFm9iyM5kNTachs2gkwRoPhkbFECYqliqo5sEzQAApXByXAK4HKwwmZw2VQVSWgadluXrpWdKIkskANVwFXV4JpdIAPAB5CTglbrRCbUAsRDSMgX1AABeX9-1IUAXwAPhA0AAApGjyBCfh+ZCUPQj8Xm-N5DEkRD0IIot4M6MsAEoQJg8F8IIlCujQRB4Wo-JyKwn90A0TIAFUmPQoi4M4z9XiRNA8Jomi+OgLpOPI4CYORUSxPQuiGLiHiUJYr8fzguQunYuJQCvGS5JEtTxIM0yCOUxjFLyKzVJ+DShPg5sunkozyQ40AAHU1KIgBtcJApvO9EAfftXwkABRVZMDvdsn3BCQvKgqCJBfPzos4G5CyfLyJD-ADIKggBdYq1K6PyytIwYolhWwsBcTBg1Ap9kkE7D3gWfxgiguCjC4XAumSSr3O+fIkGpeAMH6zhcHCRhcDoOCBR2brMlk7I1JQMhlo+Nbwmaf07BgvUtVO8IAFZyOccVtHo7RIvgcV4DggAiKZdDoJtQBEbBIE0CQgngCoTCQa4TChTgAEJXtItSJugKb9kC-k9oyCRrCMIgujglH8AIdkDNve9H0QVqoNGg4DnwoY4cOOq7DcTwHk+WpQL8rIQxaNoSNOg0DgkTnDp5rozrtAX9mF9pRZ1d0JaF7npdAPUdQOMqGdAdtrlue40eCNnQA5pt-i6V7GEgeMNVewHFZIp1VaGQXjYBUBXroYIstwfxra5o6ugAFn9tXS3LH7Zl4LqAhDYIWFqAgkC4WrhHqpm5jRp5YJwK4WDg1OWbWkQ4ZUfIAD0Szz9PhHCEhgkixJsF2yO9g2sa8hW9JgnCTGiEb1aMgO226bhhdQ614Ida8SuMGhNBYDsOhcBENwwm+y9EAJLOmt+GA2iT0Q7DHm5uF1yOM9Azec8Pif84yQuF1LktFCv4+09Pqua-gOucF7jv1pg1uI5907t3RAP9PgDyOhIdu4Cez-AkHaIeiggA"&gt;working implementation in the playground&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?&amp;amp;q=2#code/PTAEE0HsFcHICcCmoCWA7UBjAFgQ3gObKQBmo80aa6BoADtALZ0DW65uALjVpM4t26Q0AZwA0oAJ4xQeAG6IAUCFC5QJRAHdQnSOUqq0AEykxYC0ACtoIzqAKQ7nbMhEoAXskx86AlEIxNSHg2NAIAOkVFdE5EeBJcTGQAYR8-XXhQAG9FUDzQYAAqQtAASQwAGwAjEVBC4Fz8zUQUAmxOAC5QNCYquIBuRQBfKJi4hKTQAGUPRFT+QRRhUEQAD1jjWvnfQWDs0BHotFj4xOQAEURveC4UBW30pYw1jaMttN3MnPydF0ZELq2eA0YZRFRQaCZbxGZBBEK1AhILigTQuDDSaAouLENAVSSyXDGCo8bwLfxPETKMC4KowJwuUBuTygUiqehMVjsKrQOyoxDomS2fCxEy6AlEry4ESIWrElhKFTOZAw663Zaknbk4S1AC0pkxJBgxl+yOcyIxoCMKCMaFgdnkyCpv2QNJQxM4+LFiSSIlqIj4xDISpW6xu6hQiAqb3URpMy2DTsuqu49w+WrQAEJQMlCfqQ69naAAAY4K4sIvqSiYAKgPoVSCaJ1ipCMSAWYMat1xFbweB7OsNgD8oCi3lEdlLmBYoAAvKAADwAFUkvnz-OjD0+AD5QAAKIxcXBdZe+ADaAF0AJSznfffJITiQjAHzi4cKMXB0Xca9J7Ge3xofjyFAyG-NMMnCZpWnaUAdwAJgARkQ8IAFZr2cPttDQLRQAAUV7YJdwAIimXQ6ELERsAbCQ4SjcgrmCExsH8DMiMvQCgIfJ99nCXif0+CRrCMIgul3XjwnwAgRC6SgWDQBs0Ava9-32IYDg4oZ2MOMdbEZWZN38YJajnU8sixaDOlARCAE4DgkMyoLaSykIABjs-ZHPaLoEIAZgAdgANnchyWicro4J8g5z0UHS7BVYJblTMkMmM0BTOdf4uiI1s5AjEQiJo0KvNAALIqGeyMoBUAiLoYJOBufwCvMsLQAAFlaqKwTARcGSZLxwKeFFghYBEkU4UdtTsPqDJrOdJxYXdpvAoz2JUfIAD1B0UJbkqecJDXgXDEmwMDkr-ACfn4wz4HCISiFOzUIM8zgtPYp0euVBibhTfrduWFARFtOw6ClNwwkLD1fB1ebfhgNoJvHS0vsSuYBuWOaXCnfdkZ+maVqdDatsUeLvruVG-rQfbgiOnAHt-TIVLvPIrogu7EDpz5IKKzgJBZ4JwiVf5XsUIA"&gt;Our answer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-17"&gt;Update your website's color scheme for Halloween and tidy the codebase up a bit&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-18"&gt;Handle a book stores halloween discount event&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Share Your Solution
&lt;/h2&gt;

&lt;p&gt;Once you feel you have completed the challenge, you will need to select the &lt;strong&gt;Share&lt;/strong&gt; button in the playground. This will automatically copy a playground URL to your clipboard.&lt;/p&gt;

&lt;p&gt;Then either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to Twitter, and create a tweet about the challenge, add the link to your code and mention the &lt;a href="https://twitter.com/typescript"&gt;@TypeScript&lt;/a&gt; Twitter account with the hashtag &lt;a href="https://twitter.com/search?q=%23TypeOrTreat"&gt;#TypeOrTreat&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave us a comment with your feedback on the &lt;a href="https://dev.to/typescript"&gt;dev.to&lt;/a&gt; post, or in this post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Resources for Additional Help
&lt;/h3&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The New TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Community Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The comments on each &lt;a href="https://dev.to/typescript"&gt;Dev.to&lt;/a&gt; post!&lt;/li&gt;
&lt;li&gt;Our previous &lt;a href="https://www.typescriptlang.org/play/#gist/303ebff59a6fc37f88c86e86dbdeb0e8-0"&gt;&lt;code&gt;Type | Treat&lt;/code&gt; 2020 challenges&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat 2021 - Day 3</title>
      <dc:creator>Orta</dc:creator>
      <pubDate>Wed, 27 Oct 2021 20:25:16 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-2021-day-3-54b0</link>
      <guid>https://forem.com/typescript/type-treat-2021-day-3-54b0</guid>
      <description>&lt;h1&gt;
  
  
  Type | Treat Challenge 3
&lt;/h1&gt;

&lt;p&gt;Welcome to the third &lt;code&gt;Type | Treat&lt;/code&gt; challenge! These challenges are a series of blog posts which have 2 code challenges in, one for beginners and one for intermediate TypeScript programmers. We're on day three, which means going over the answers from &lt;a href="https://devblogs.microsoft.com/typescript/type-treat-2021-day-2/"&gt;yesterday&lt;/a&gt; and have 2 new challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;There is many ways to decide how to type existing data, you could use &lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types"&gt;literal types&lt;/a&gt; when you're sure of the exact formats - or be more liberal and use &lt;code&gt;string&lt;/code&gt; when you expect a variety. We opted for literals, but using &lt;code&gt;string&lt;/code&gt; is totally cool too.&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;UnderripePumpkin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&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;soundWhenHit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dull thud&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RipePumpkin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orange&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;soundWhenHit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;echo-y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;OverripePumpkin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;color&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="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;soundWhenHit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;squishy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second part of the challenge used &lt;a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates"&gt;type predicates (or type guards)&lt;/a&gt; annotates a function which returns a &lt;code&gt;booleon&lt;/code&gt; with narrowing information about the paramters. This means we can tell TypeScript that when the return values to &lt;code&gt;isRipe&lt;/code&gt;is true, then the argument &lt;code&gt;pumpkin&lt;/code&gt; is of the type &lt;code&gt;RipePumpkin&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- function isRipe(pumpkin: any) {
&lt;/span&gt;&lt;span class="gi"&gt;+ function isRipe(pumpkin: any): pumpkin is RipePumpkin {
&lt;/span&gt;       return "soundWhenHit" in pumpkin &amp;amp;&amp;amp; pumpkin.soundWhenHit === "echo-y"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successfully completing this challenge would have no errors, and the type for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbwMYQgawAoFdxuAOwGUIswBfOAMyghDgCIYBPMAUwFpp2YpWBDGPQBQQgPSi4ATRIByXnAAWrADZgCAczgl4AuHzjKISPsqqoAJuwBGffGjg8mGhxDgBnaDrESrwTWuVWLUo4MBwwPHw3OAIYVw8QVhgFZwB3FKQFGOisNz4rQLMoOBA+SPVvOAAVBT5gUPDI9xIwOAAKPnNzZsSDVhAIfHUoPjc3ABo4TOBlZXrbbpQUfCx4EBm0ADoAShFlt3gw3AI3AC44bGP8AG0AXTgAXjhroTg3xCmIQyhz+mHWVj4eiTDxYfDmADqSnwAAlgDBfuYsLMHAosOZ6HAyONXu8EJ9vr8wlAwIFgc0wZDoXCEQxWJkIOwmJjsbi3viUISGP9AeTQeCoYCaYjkaZkuiWTj3h9OdBful4aw+SQBdT4b83ABHLDANwKZlYqV4glyhjQWzqJUglVUoXqukMpmStkyr6mv68XnWymC2H2+hIlHijGGl0ct0-M0jIZWimqu20+j0hSMg2s6Xhrn0ApYWP821+xPJ1POjMmyP0c0x5U+tVFx1poT3ETiOAAYVscCYJDgrAAHjw+Eh4Mkgsw2NFKNBUZ64OZgJRKKxePh4MYYKx1NBgKxohAQqO3EEjhETgB+ETjoIAVXBy6gwDYl1P+EeiBdsorPKBRre+d9woMIGYpohiQhkEIV5wAASo+rDPk0TwIB+EZElgJJknAAA+UYWkq2EMDmVouv+da-MWTrgZBLBBAA8gAbvecEIQQb7IdKn6-N+mI4fQCobsCJE2gB-pajqerMlRlQQqwMgorkQT6FBYLAIMLjuHwTCoro+gnk0xivlYin4Fp+6orux4QGMwAFGONFuJeNEXI0rFPHAt7mExT4ua+OGwd5VwEQxXnwT5LYSAAMqgaDRFuEDmJM+AQKkfQwNEpRoIpoQ7pMqRBKktgjq4lDAFABxwJa8DaHoKJmaOcAPmwDRXG4myVDUuqfJ5cCpNAMV6PAUBgjAoCsJMVirNUNGEEgjXwOYEC7vgMjwEe-TqZSy4HAs2nwAABnpJwAGLQBgO57ZUnWDMoWn+aFVwyNESWpJs7adt2WCogQ9hmfoBVaXEUy1DG5lwHtup3Xt6l-FgfBQCG9WMDR9AXkIlBgsOqmvhDcFtId+DnCx+DbOc+PZDBzE+e+0q8DA6GvvQpEJpirFkwAZGzzUvpsTOFo8DxPEmDbCBBQj7IcPluCdUBnUETz461JXKBuUBtDjbC7K27wAHoXuLFKtE8KDoETxCkHjkvS7LmsSDrF5AA"&gt;Our answer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;This challenge was first about understanding different read vs write properties available in both &lt;code&gt;classes&lt;/code&gt; and &lt;code&gt;interface&lt;/code&gt;/&lt;code&gt;typed&lt;/code&gt; objects. Personally, I've seen this with &lt;code&gt;document.location&lt;/code&gt; a lot where you always get a rich object when you read but can write to that property with a string. We wanted a similar concept, but using &lt;code&gt;punch&lt;/code&gt; which for me is generally a 'throw it all in and see what happens' style of drink.&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;PunchMixer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Punch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;flavour&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="na"&gt;ingredients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]};&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Punch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Punch&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Punch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ingredients&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;punch&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ingredients&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;punch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flavour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;punch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;punch&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;punch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ingredients&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;punch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solution uses a mix of private class fields, indexed types and type narrowing to set up a local punch object which is always returned. &lt;/p&gt;

&lt;p&gt;The next step was to make this class generic in some form so that a type parameter passed in to the class would dictate what the return value of a &lt;code&gt;vend&lt;/code&gt; function was.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- class PunchMixer {
&lt;/span&gt;&lt;span class="gi"&gt;+ class PunchMixer&amp;lt;MixerType&amp;gt; {
+    mixer!: MixerType;
&lt;/span&gt;
  // ...
&lt;span class="gi"&gt;+   public vend(): MixerType {
+        return this.mixer;
+    }
&lt;/span&gt;  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We were not too worried about how you passed back the &lt;code&gt;MixerType&lt;/code&gt; - our first draft had &lt;code&gt;return {} as MixerType&lt;/code&gt; but a private field feels nicer. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEHUFMBsGMHsC2lQCMCGsDWoBmAnJUAT3gFd9RDV4AXAS1gGdQALTHWdRABwEJQATXIByAG4pUkSADtQ6JlkgATUPVwAoECXKgucskxSkKoGZADuoRfWjQWteKETol8qvBq1QF1o1Zs6DLK0JAsWmCI9AAe9DIA5qC0rCg8ZDKwAbjwlEGgZDwIUQmgPOj4tMQAdBoRoAAK6ZlqLHlxtJD4YQwlyvhxOFJchsa6+qVk3uh21jm0LPC4SX4JTHXtTvS0ADQkkN5bLfLQFujELLDQCkaqCqAARGkZrPc+KXImzq4o6HoFNRpKjwUI1nqAALygADeGlAcLwVzE5HwAC5rLR+glYfC4vEusp6LJ5miABRMDG40AAH2heHwZC2aPJmPiuxkZEQUlRZg5XNAAF8AJQAbQAuhp+bVtFBxCgXDxgapyN5fOgVbZoIEFbJ5N4TJQyhViLtxp8LP0Ou5Ltc6r5-D4clgWBYtgFpprkpIYPArAhlJAAPygWrWpgsUGZACyMU6AB5o9FOgAVYjAgB80OxcIAxE9MmiIwFIVDcIjkWiRCJdrj8YSZMTQGL+QBuLPOGP4PhohPJ1OQVtttKoaCMUDxfYTZ4kwUFpoBGHwxdUfYUOTJehMKq5uetxeSwdkYejozePOsEln2dgmmF4UiGsqOvzESi4XszmdUWCzNLnFLElApAiyTs04JgaAIjMriIjfguv5Luum7bs8VQPgSRKbmkTDnmegq7vB-KgDARhqP+IilugSIUCIahyLhP7wYuiFbmeEIgaw+G-oRxEoHBjFwsxyGZKhCS1hhVRYThc54W2e5tvui5DiOsCgBIwTTt2HYpsCDG-l0tCrssG5VFEib4JxAoSlKYAkuoOhkD4QTeI4ST4MQRnOq6yp6FcYZhLsnzjH08A8MsKDmFYUjQD62x1KgkygHQKT4C6Ri7DwoQKCgmUSB5ejwP6xzwOYgohsV5LtmZbERQ0c49vg07WaAADKSA-LADDlW89rsNqcjKBQlKeqU5SVLsLhxNA7kjKoLliNM9DKGqkB1PqPnXA6+BOvILCQNEwIdSoZUyBVRLJik9Sje5kIkjI3CQEyFIJN+4IZlCkoICd3h4ugqAAIIAOK+SwN13cgj0sulc5XpkL1vR95XOSFACqPCFmxt33RDuJQ88MOsHD0II198jKMoACSsAoDdl61c8hPvbUGi4E0nV0VdzW0KNTDTrppMU1TJKmZ0EnSW2bZnfgSYXVdJL3H99ylYuwv4KLYKQvcAMMuYYagAADFUev3LUi6S9LkCXUacsAEKK22Ktq6BtIEAytBovczLoBYXL9GE9xsrynRogAbJZEv1udFuy-cADCduLj9-1A9cNv+5VIu4W2jg8KjhZy3H40do7BPBvbRescWdKu+7P3AkwafvlyaIAEwAMyWcr5dzmx9z1HEkDoAqoSgAAUgyVPG222gkiFbPTNWSyfPSa5+BcBUoEw3AZZAuyIdYrDkNAqgyHQRH4IQ+BK3+oBC13KFoU+m6hAkySgHw4EACywbJ+UnfAoRVE6BfOWrVkDrhKPEU+wtVAFFomFdi8d4SSn3NoS23hm5HF+LgSwoARw6zQN6KwiENCGkqJzbmjUmox2Kj9eYu92AqkdCoRKCULAwE1CSNhbAQqQD4N+JgTgTAiFUCOJQdQXJMC4MPNaPD8BqnoMVJITh2DBGHi4GQ7kVYsDiPA0h1RgzaCTE4ZQThkhqnssI3B9A3AuRcDYlI61dbjnMP0KRU15DzVsL9UIdQgizWUZRH4eBWYKLkNkSgakCQlG8p6eglBQxGBYAAWjME4cwR1tAuQsDkNySinCIDIM0X6MSHH0F4KEZA9Z5GKP9FzWwLBkooAAFaGFoHUcczkHGAWdI6Skdw9oHQ6MoKopdAItX-vAGOsDK4IGitye4+JXiSjGcnXWlcmD0AAF4PQeEwFwdglm1BZhkNmI0KiEiYH9Wgf0NHNSkZAXmcFPoVRHGIXEAAleASB6rVRwYWeqsZWrRSmTwNMjU4TPO8FgLYmRZA-MhDVf5HZYyrKYGC0q2IzYyytvLRB0LaCwpkPVYuPdOZuWIFgY2ELEZjmBmxfFhLiWRPBaAbQ8IAB6AZsTxGBlUDZ2ymZwixVHHFtsr6vI+V8xAxKK4PHeawQ85RUCj3HpAKlv8KqwGmVYt5CRPnfKLsyq+bK4ScuxFqngVRZk5CskAA"&gt;Our Answer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-9"&gt;Figure out how to stop people giving you bad strings for your custom lengths.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-10"&gt;Stop losing your literals in Halloween posters&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Share Your Solution
&lt;/h2&gt;

&lt;p&gt;Once you feel you have completed the challenge, you will need to select the &lt;strong&gt;Share&lt;/strong&gt; button in the playground. This will automatically copy a playground URL to your clipboard.&lt;/p&gt;

&lt;p&gt;Then either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to Twitter, and create a tweet about the challenge, add the link to your code and mention the &lt;a href="https://twitter.com/typescript"&gt;@TypeScript&lt;/a&gt; Twitter account with the hashtag &lt;a href="https://twitter.com/search?q=%23TypeOrTreat"&gt;#TypeOrTreat&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave us a comment with your feedback on the &lt;a href="https://dev.to/typescript"&gt;dev.to&lt;/a&gt; post, or in this post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Resources for Additional Help
&lt;/h3&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The New TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Community Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The comments on each &lt;a href="https://dev.to/typescript"&gt;Dev.to&lt;/a&gt; post!&lt;/li&gt;
&lt;li&gt;Our previous &lt;a href="https://www.typescriptlang.org/play/#gist/303ebff59a6fc37f88c86e86dbdeb0e8-0"&gt;&lt;code&gt;Type | Treat&lt;/code&gt; 2020 challenges&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat 2021 - Day 2</title>
      <dc:creator>Orta</dc:creator>
      <pubDate>Tue, 26 Oct 2021 19:35:06 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-2021-day-2-1ojn</link>
      <guid>https://forem.com/typescript/type-treat-2021-day-2-1ojn</guid>
      <description>&lt;h2&gt;
  
  
  Type | Treat Challenge 2
&lt;/h2&gt;

&lt;p&gt;Welcome to the second &lt;code&gt;Type | Treat&lt;/code&gt; challenge! These challenges are a series of blog posts which have 2 code challenges in, one for beginners and one for intermediate TypeScript programmers. We're on day two, which means going over the answers from yesterday and 2 new challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;The first part of the solution for this challenge used &lt;code&gt;as const&lt;/code&gt; to trigger "Literal Inference" - basically telling TypeScript "Don't convert the array to &lt;code&gt;string[]&lt;/code&gt; but consider it a constant set of string literals. This meant that &lt;code&gt;playlist[0]&lt;/code&gt; stopped returning &lt;code&gt;string&lt;/code&gt; and started returning &lt;code&gt;"The Legend of Sleepy Hollow by The Monotones.mp3"&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  const playlist = [
      "The Legend of Sleepy Hollow by The Monotones.mp3",
      ...
&lt;span class="gd"&gt;- ]
&lt;/span&gt;&lt;span class="gi"&gt;+ ] as const
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second part of the challenge used &lt;a href="https://www.typescriptlang.org/docs/handbook/2/typeof-types.html"&gt;&lt;code&gt;typeof&lt;/code&gt; types&lt;/a&gt; to extract the type from the &lt;code&gt;playlist&lt;/code&gt; array. Without the first change, this would be &lt;code&gt;string&lt;/code&gt; but after the change this meant the full array of different types. You then needed to use the &lt;a href="https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html"&gt;type index syntax&lt;/a&gt; &lt;code&gt;[number]&lt;/code&gt; to declare that you want any potential string from that array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- function playSong(song: string) {
&lt;/span&gt;&lt;span class="gi"&gt;+ function playSong(song: typeof playlist[number]) {
&lt;/span&gt;      api.play(song)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Successfully completing this challenge would raise an error in the final code samples due to a subtle typo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEEkDtQBwJwKbwIYBcCWB7aAzTdQALZAGxMwHcEFIAaUAT0wFcByANwVACMEBjTAFsuqQlwDOxRABNQAEQBSoPHABQIUKRKMWBHHHQ1p4gHSgAmiw4SEqUMxihREhuNQJBTzKGno3B7mZ3JzFQQWZxdD51MAj0SABzEK5CdEdIBAonBhgEdBwGUABBAAVwMFBVVXRBGHw7AG9UHLyC0vAAX2U4IVAAImbcgFp8IdREND6qgUg3WBJkBhI-OwBeUABtVVAd-oAVUIAZBASjUEwcUABlEmoYQoAJTDJKHkKDrgBZbExUbARTLUAMx9WjbXZ9AAU4FQrHEmgAlKBvrN3HA4aAnstpIs3qAAELMPgAa1AAHkqLMTMDQeCdn18d5PtRUPDnMjsG4EARuIVGfJ0NJpLcGNSYCCwbt+iVmHAYLdQCUEJh5VwAKJobnIlls0IAdXQqD4hHkmD4fx571C+PQSUZMFycDFErp-SufAmgniBK0oEhaHkcGQfGYC0xWiRvNAH3kzBK2FZztpUoZaEEyDooD1zxw6czADEg5BiTQufF6PhA8HQ8g8TG5OhkIJsMYk5KIYWMyXUXloHsKCs66EAMJwVyoUiA8XJiGsA4GMjc1h4z5RYgIbQKYPE8TYJOqAC6mnhMzcVXli2WZ40AD0APwxaMtd0GGB2UTxHchPygH+1q92BcoD+PECTiPQFCpMav5snAzBcEMPBBKAfAZjozCVBo6Ylk+uQvmk74TO+oQXksg7IHAQaFM2iD9MgJ6chOkCsn0D6qKedjIDA6CgOsgytAw7SQn0ggMAA+lx6BiSWDB9AiqiSSYMwZOakLyaoODMJA5pYNApFXNgCSQruiQAFzZLkQGkQBGyQMwgi8HAB5Ig0rqKaRxmGfJHTngsDAGYkwkynKCpKiqCoami2q2LqXAGkaJpyGaFpDlwNp2iqjpJupGgHD+FD4F+CREQAhASyGGihLAkLIvCaKAyyoKgCo0VwiCRFyzFeBZmDgShaFMMwj4fsW5yXLWFC4n8KHEIkIihAABvphkLaAC0mQkq0wBRTa2FqiARPNXADC0Fx9MkmFgNZKz0LuIQBnsz4egRoBBn4AKaNA3I9AQ+TJIgGK1oMmBsctgVQjCgNIiiXLovCWKCriUaEiS5KUlOILyWDRl9DGxynJAshATcdyPM85BZFGMYor8-wY3JqjY8J+Jphm9DZiQuZs6AnbFqW7jlucBByBRIZhlToQNk2Lb0wiQA"&gt;Our answer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;This pattern is quite common in code we write in TypeScript codebases, you create one function which takes the result of another and keeps passing objects between functions in a pipeline. One of the best techniques for simplifying this design pattern is to use &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype"&gt;&lt;code&gt;ReturnType&lt;/code&gt;&lt;/a&gt; with &lt;a href="https://www.typescriptlang.org/docs/handbook/2/typeof-types.html"&gt;&lt;code&gt;typeof myFunc&lt;/code&gt;&lt;/a&gt; to map the return type of one function to the paramter of another. This removes the need for intermediary types which need to be updated when the functions change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  const findOldCostume = () =&amp;gt; {
      // ...
      return { jumpSuit, estimate }
  }

- const createNewMask = (costume: any) =&amp;gt; {
&lt;span class="gi"&gt;+ const createNewMask = (costume: ReturnType&amp;lt;typeof findOldCostume&amp;gt;) =&amp;gt; {
&lt;/span&gt;      // ...
      return { ...costume, mask }
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The little extra step at the end was a small reminder that you can use this technique to provide a type which can be re-used everywhere.&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;Costume&lt;/span&gt; &lt;span class="o"&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;assembleCostume&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;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEGEHsGcBcFcC2BTUAHATstpYEsUAaUAT0nlADM8BzeLUAIgHcALE0AO0llABMs0aKHg4ANngDWyAFAhcrVAENOsJTUic8cYXk4LUAZQCO8PH1ABxJSgD8jYnl7RkyRMMzJYsDsiXQSOTAAI39kC01ScgxQSDELcH8lflQABSU0ZDFY+FhqWAA6UCDQAApQVm80aAAuED54AGNJBuaNAsbIRGBbYwBeRqSAaj5kIbQMrIAyPCUADz6CdWRoGaVFxGXoAEoZEoBNclAXXn9zVHwUXEgqWnpUcl42JV4yeAByBg09GmuuVwssBuJU6nAAbsgMLxYIpQKC4EhlJwLNBpLBGqwctDYWgeMhVLNssxIBhJNcSjQ8BCovQXGJKKAVKBzslIAzLitBmJkDU9gRcVDQABvFxKDAY4iYPSwSEAXyoGC6TB8mQAtCTVbAsC9GHt4bxqMiAPLxKAIq59MrbUB9AB8wpkoCdcM0cFAACskGhDGZeJbReLWAUXvhGqVrQAfCPHPyBjpiGBecOgKMxsUYgo0MXLcOO5360ArS4vVCWgDMAAY806sAgMPohR6vT6nMQi0sZaBZTJuzIC41tTKAHLIZgAWX8ZMtpU65p5oAASl56JwACokTIAHhVyDZt2NppgCBQtutdodzpdnDdm1RNvQGGlkIKUtUE9Rucvt8kBWgrEm96MI0eDityuqXrOx7IAU7abJ2QyWgAbFWl61iuwqgAUWGQYixDfl2PZ6q6vADn4MoAEKQHwJCJCgGDJNOOEoDUTpLnWa4bsg26cXupEliO46TqeNr2kK1ZXm6gx0QxD5PhgL6PqotGQkon7OvIACSTx4GI2ScAC6BKNKPzXJA4lMdBsElqACGgAALAArOJaH1hhWEdEeuFwjYKkEb2Bb+C4iDBNyZpQfeybnmJqHLq5fEUVRNE+fRM6DsgAnvpIpSGnwJp8GFiLhtsuy9vIliDsQMLaHCaXCEygVuCFHASPpsQMkoukGIZUJ1ciJQwqgxKkjS-zhH8fCQEUAASkDMMgEIYI4vBYBIKyxPoAAGKgkBtwhsHgGLFPImzSHtJKSCZzBOJiA2Mo0CAdS6c6MqAwROIywV3OQtREdeJGeRajJCI1oUA8gubyM6AB6th7PIiT6G8Ch6GSe7JMwSgcECtxzF1eiUJC+KNIN12PDVZE-CU+nMKAG07rtsQxBtcmUEoxO7cQJKgFgaBiGzJm3dte3XbTjbuV2G2wyUGmjB1YhY6w1U7numCQCFbjefowSoNAcQQiiNwwi8I2DJwJQncocL-pwNCoHo60POysKUPAnD3XgrqMsiXA8KNgI3KIfDWbdO7QAUcNgIcHydZI3A0+9Q3SBYbD4sjwgtag9HaGtTKQoqGB9q6cTQQmNClBtWnHKw5DxLgSjSIywRkwAJEKFkFBy8qIHouQrBtuwlEOs0KMbc3vNSGinKAicmWgeCZBnxCmyNtv6fRnbJDuJT7YdPOCPisDCLd+J8KqcDWWjwPBaDz26yPvA8IoGDQCCTJYKq8AuMyvB8zKGBSzuCAYN7xsRXOuLcyt2pX3VgVE8QA"&gt;Our Answer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-5"&gt;Help sort out a large array of pumpkins, and then get cooking soup.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-6"&gt;Fresh back from robotics camp, can you make the perfect punch mixer bot?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Share Your Solution
&lt;/h2&gt;

&lt;p&gt;Once you feel you have completed the challenge, you will need to select the &lt;strong&gt;Share&lt;/strong&gt; button in the playground. This will automatically copy a playground URL to your clipboard.&lt;/p&gt;

&lt;p&gt;Then either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to Twitter, and create a tweet about the challenge, add the link to your code and mention the &lt;a href="https://twitter.com/typescript"&gt;@TypeScript&lt;/a&gt; Twitter account with the hashtag &lt;a href="https://twitter.com/search?q=%23TypeOrTreat"&gt;#TypeOrTreat&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave us a comment with your feedback on the &lt;a href="https://dev.to/typescript"&gt;dev.to&lt;/a&gt; post, or in this post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Resources for Additional Help
&lt;/h3&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The New TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Community Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The comments on each &lt;a href="https://dev.to/typescript"&gt;Dev.to&lt;/a&gt; post!&lt;/li&gt;
&lt;li&gt;Our previous &lt;a href="https://www.typescriptlang.org/play/#gist/303ebff59a6fc37f88c86e86dbdeb0e8-0"&gt;&lt;code&gt;Type | Treat&lt;/code&gt; 2020 challenges&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat 2021 - Day 1</title>
      <dc:creator>Orta</dc:creator>
      <pubDate>Tue, 26 Oct 2021 07:09:21 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-2021-day-1-6an</link>
      <guid>https://forem.com/typescript/type-treat-2021-day-1-6an</guid>
      <description>&lt;h2&gt;
  
  
  Type or Treat Challenges
&lt;/h2&gt;

&lt;p&gt;Today we're starting up our second year of &lt;code&gt;Type | Treat&lt;/code&gt; (or "Type or Treat".) We will be presenting some "spooky" code challenges that will allow you to dig deeper into the TypeScript language in a fun way.&lt;/p&gt;

&lt;p&gt;Starting right now, a new code challenge will be posted every weekday, along with its solution the day after. The last solution will be posted on the weekend.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Participate
&lt;/h2&gt;

&lt;p&gt;In order to participate you only need to be able to access the &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript website&lt;/a&gt;. Though ideally, you share with us your answers via our &lt;a href="https://dev.to/typescript"&gt;dev.to blog post mirrors&lt;/a&gt;, here, or via Twitter to &lt;a href="https://twitter.com/typescript"&gt;@TypeScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You will want to start here on the blog to find the details on the code challenges for the day. Each post contains 2 links to different challenges which run in the TypeScript playground. Via the playground, you can work on the challenge in your browser and you will be able to test your code live to see if it properly passes the challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  How To Share Your Solution
&lt;/h3&gt;

&lt;p&gt;Once you feel you have completed the challenge, you will need to select the &lt;strong&gt;Share&lt;/strong&gt; button in the playground. This will automatically copy a playground URL to your clipboard.&lt;/p&gt;

&lt;p&gt;Then either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to Twitter, and create a tweet about the challenge, add the link to your code and mention the &lt;a href="//twitter.com/typescript"&gt;@TypeScript&lt;/a&gt; Twitter account with the hashtag &lt;a href="https://twitter.com/search?q=%23TypeOrTreat"&gt;#TypeOrTreat&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave us a comment with your feedback on the &lt;a href="https://dev.to/typescript"&gt;dev.to&lt;/a&gt; post, or in this post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Resources for Additional Help
&lt;/h3&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The New TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Community Discord&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The comments on each &lt;a href="https://dev.to/typescript"&gt;Dev.to&lt;/a&gt; post!&lt;/li&gt;
&lt;li&gt;Our previous &lt;a href="https://www.typescriptlang.org/play/#gist/303ebff59a6fc37f88c86e86dbdeb0e8-0"&gt;&lt;code&gt;Type | Treat&lt;/code&gt; 2020 challenges&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Day 1 Challenges
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Beginner/Learner Challenge
&lt;/h4&gt;

&lt;p&gt;Using the new music streaming service from the TypeScript team, Typify, set up and share your halloween playlist with your friends.&lt;/p&gt;

&lt;p&gt;Head to &lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-1"&gt;this link&lt;/a&gt; and help us figure out the best type to use in one of our function parameters!&lt;/p&gt;

&lt;h4&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h4&gt;

&lt;p&gt;You've figured out your costume, but making it is a bit of a process. Can you figure out how to make all of the parts come together in a type-safe way?&lt;/p&gt;

&lt;p&gt;Head over &lt;a href="https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-2"&gt;to start sorting&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Announcing TypeScript 4.1</title>
      <dc:creator>Daniel Rosenwasser</dc:creator>
      <pubDate>Sat, 21 Nov 2020 00:50:31 +0000</pubDate>
      <link>https://forem.com/typescript/announcing-typescript-4-1-1ld5</link>
      <guid>https://forem.com/typescript/announcing-typescript-4-1-1ld5</guid>
      <description>&lt;p&gt;Today we're proud to release TypeScript 4.1!&lt;/p&gt;

&lt;p&gt;If you're unfamiliar with TypeScript, it's a language that builds on JavaScript by adding syntax for type declarations and annotations. This syntax can be used by the TypeScript compiler to type-check our code, and then output clean readable JavaScript that runs on lots of different runtimes. Static type-checking can tell us about errors in our code before we even run it, or before we even save our files thanks to TypeScript's rich editing functionality across editors. But beyond error-checking, TypeScript powers things like completions, quick fixes, and refactorings for both TypeScript &lt;em&gt;and&lt;/em&gt; JavaScript in some of your favorite editors. In fact, if you already use Visual Studio or Visual Studio Code, you might already be using TypeScript when you write JavaScript code!&lt;br&gt;
So if you're interested in learning more, &lt;a href="https://www.typescriptlang.org/"&gt;check out our website&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;But if you're already using TypeScript in your project, you can either get it &lt;a href="https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild"&gt;through NuGet&lt;/a&gt; or use npm with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also get editor support by&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-41"&gt;Downloading for Visual Studio 2019/2017&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://code.visualstudio.com/insiders"&gt;Installing the Insiders Version of Visual Studio Code&lt;/a&gt; or following directions to &lt;a href="https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions"&gt;use a newer version of TypeScript&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this release, we have some exciting new features, new checking flags, editor productivity updates, and speed improvements. Let's get a look at what 4.1 brings!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Template Literal Types&lt;/li&gt;
&lt;li&gt;Key Remapping in Mapped Types&lt;/li&gt;
&lt;li&gt;Recursive Conditional Types&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--noUncheckedIndexedAccess&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paths&lt;/code&gt; without &lt;code&gt;baseUrl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;checkJs&lt;/code&gt; Implies &lt;code&gt;allowJs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;React 17 JSX Factories&lt;/li&gt;
&lt;li&gt;Editor Support for the JSDoc &lt;code&gt;@see&lt;/code&gt; Tag&lt;/li&gt;
&lt;li&gt;Breaking Changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Template Literal Types
&lt;/h2&gt;

&lt;p&gt;String literal types in TypeScript allow us to model functions and APIs that expect a set of specific strings.&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;setVerticalAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;middle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bottom&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;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;setVerticalAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;middel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//                   ~~~~~~~~&lt;/span&gt;
&lt;span class="c1"&gt;// error: Argument of type '"middel"' is not assignable to&lt;/span&gt;
&lt;span class="c1"&gt;//        parameter of type '"top" | "middle" | "bottom"'.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty nice because string literal types can basically spell-check our string values.&lt;/p&gt;

&lt;p&gt;We also like that string literals can be used as property names in mapped types. In this sense, they're also usable as building blocks.&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;Options&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="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noImplicitAny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strictNullChecks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strictFunctionTypes&lt;/span&gt;&lt;span class="dl"&gt;"&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="c1"&gt;// same as&lt;/span&gt;
&lt;span class="c1"&gt;//   type Options = {&lt;/span&gt;
&lt;span class="c1"&gt;//       noImplicitAny?: boolean,&lt;/span&gt;
&lt;span class="c1"&gt;//       strictNullChecks?: boolean,&lt;/span&gt;
&lt;span class="c1"&gt;//       strictFunctionTypes?: boolean&lt;/span&gt;
&lt;span class="c1"&gt;//   };&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there's another place that that string literal types could be used as building blocks: building other string literal types.&lt;/p&gt;

&lt;p&gt;That's why TypeScript 4.1 brings the template literal string type. It has the same syntax as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals"&gt;template literal strings in JavaScript&lt;/a&gt;, but is used in type positions. When you use it with concrete literal types, it produces a new string literal type by concatenating the contents.&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;World&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;World&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;// same as&lt;/span&gt;
&lt;span class="c1"&gt;//   type Greeting = "hello world";&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens when you have unions in substitution positions?&lt;br&gt;
It produces the set of every possible string literal that could be represented by each union member.&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;Color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SeussFish&lt;/span&gt; &lt;span class="o"&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;Quantity&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; fish`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// same as&lt;/span&gt;
&lt;span class="c1"&gt;//   type SeussFish = "one fish" | "two fish"&lt;/span&gt;
&lt;span class="c1"&gt;//                  | "red fish" | "blue fish";&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be used beyond cute examples in release notes. For example, several libraries for UI components have a way to specify both vertical and horizontal alignment in their APIs, often with both at once using a single string like &lt;code&gt;"bottom-right"&lt;/code&gt;. Between vertically aligning with &lt;code&gt;"top"&lt;/code&gt;, &lt;code&gt;"middle"&lt;/code&gt;, and &lt;code&gt;"bottom"&lt;/code&gt;, and horizontally aligning with &lt;code&gt;"left"&lt;/code&gt;, &lt;code&gt;"center"&lt;/code&gt;, and &lt;code&gt;"right"&lt;/code&gt;, there are 9 possible strings where each of the former strings is connected with each of the latter strings using a dash.&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;VerticalAlignment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;middle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bottom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;HorizontalAlignment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Takes&lt;/span&gt;
&lt;span class="c1"&gt;//   | "top-left"    | "top-center"    | "top-right"&lt;/span&gt;
&lt;span class="c1"&gt;//   | "middle-left" | "middle-center" | "middle-right"&lt;/span&gt;
&lt;span class="c1"&gt;//   | "bottom-left" | "bottom-center" | "bottom-right"&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setAlignment&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;VerticalAlignment&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;HorizontalAlignment&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;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;setAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top-left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// works!&lt;/span&gt;
&lt;span class="nx"&gt;setAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top-middel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// error!&lt;/span&gt;
&lt;span class="nx"&gt;setAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top-pot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// error! but good doughnuts if you're ever in Seattle&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While there are &lt;strong&gt;lots&lt;/strong&gt; of examples of this sort of API in the wild, this is still a bit of a toy example since we could write these out manually. In fact, for 9 strings, this is likely fine; but when you need a ton of strings, you should consider automatically generating them ahead of time to save work on every type-check (or just use &lt;code&gt;string&lt;/code&gt;, which will be much simpler to comprehend).&lt;/p&gt;

&lt;p&gt;Some of the real value comes from dynamically creating new string literals. For example, imagine a &lt;code&gt;makeWatchedObject&lt;/code&gt; API that takes an object and produces a mostly identical object, but with a new &lt;code&gt;on&lt;/code&gt; method to detect for changes to the 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;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeWatchedObject&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;Homer&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;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// give-or-take&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Springfield&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;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstNameChanged&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="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="s2"&gt;`firstName was changed!`&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;Notice that &lt;code&gt;on&lt;/code&gt; listens on the event &lt;code&gt;"firstNameChanged"&lt;/code&gt;, not just &lt;code&gt;"firstName"&lt;/code&gt;. How would we type this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PropEventSource&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;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;eventName&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="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Changed`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="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;/// Create a "watched object" with an 'on' method&lt;/span&gt;
&lt;span class="c1"&gt;/// so that you can watch for changes to properties.&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeWatchedObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;PropEventSource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we can build something that errors when we give the wrong property!&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!&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;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&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="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;// error!&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;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frstNameChanged&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="o"&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;We can also do something special in template literal types: we can &lt;em&gt;infer&lt;/em&gt; from substitution positions. We can make our last example generic to infer from parts of the &lt;code&gt;eventName&lt;/code&gt; string to figure out the associated property.&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;PropEventSource&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;on&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;eventName&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;K&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Changed`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&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="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeWatchedObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;PropEventSource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeWatchedObject&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;Homer&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;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Springfield&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;// works! 'newName' is typed as 'string'&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;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstNameChanged&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newName&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;// 'newName' has the type of 'firstName'&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="s2"&gt;`new name is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;newName&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="s2"&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;// works! 'newAge' is typed as 'number'&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;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ageChanged&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newAge&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newAge&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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="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="s2"&gt;warning! negative age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we made &lt;code&gt;on&lt;/code&gt; into a generic method. When a user calls with the string &lt;code&gt;"firstNameChanged'&lt;/code&gt;, TypeScript will try to infer the right type for &lt;code&gt;K&lt;/code&gt;. To do that, it will match &lt;code&gt;K&lt;/code&gt; against the content prior to &lt;code&gt;"Changed"&lt;/code&gt; and infer the string &lt;code&gt;"firstName"&lt;/code&gt;. Once TypeScript figures that out, the &lt;code&gt;on&lt;/code&gt; method can fetch the type of &lt;code&gt;firstName&lt;/code&gt; on the original object, which is &lt;code&gt;string&lt;/code&gt; in this case. Similarly, when we call with &lt;code&gt;"ageChanged"&lt;/code&gt;, it finds the type for the property &lt;code&gt;age&lt;/code&gt; which is &lt;code&gt;number&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Inference can be combined in different ways, often to deconstruct strings, and reconstruct them in different ways. In fact, to help with modifying these string literal types, we've added a few new utility type aliases for modifying casing in letters (i.e. converting to lowercase and uppercase characters).&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;EnthusiasticGreeting&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&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;Uppercase&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;HELLO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EnthusiasticGreeting&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// same as&lt;/span&gt;
&lt;span class="c1"&gt;//   type HELLO = "HELLO";&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new type aliases are &lt;code&gt;Uppercase&lt;/code&gt;, &lt;code&gt;Lowercase&lt;/code&gt;, &lt;code&gt;Capitalize&lt;/code&gt; and &lt;code&gt;Uncapitalize&lt;/code&gt;. The first two transform every character in a string, and the latter two transform only the first character in a string.&lt;/p&gt;

&lt;p&gt;For more details, &lt;a href="https://github.com/microsoft/TypeScript/pull/40336"&gt;see the original pull request&lt;/a&gt; and &lt;a href="https://github.com/microsoft/TypeScript/pull/40580"&gt;the in-progress pull request to switch to type alias helpers&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Key Remapping in Mapped Types
&lt;/h2&gt;

&lt;p&gt;Just as a refresher, a mapped type can create new object types based on arbitrary keys&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;Options&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="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noImplicitAny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strictNullChecks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strictFunctionTypes&lt;/span&gt;&lt;span class="dl"&gt;"&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="c1"&gt;// same as&lt;/span&gt;
&lt;span class="c1"&gt;//   type Options = {&lt;/span&gt;
&lt;span class="c1"&gt;//       noImplicitAny?: boolean,&lt;/span&gt;
&lt;span class="c1"&gt;//       strictNullChecks?: boolean,&lt;/span&gt;
&lt;span class="c1"&gt;//       strictFunctionTypes?: boolean&lt;/span&gt;
&lt;span class="c1"&gt;//   };&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or new object types based on other object 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="c1"&gt;/// 'Partial&amp;lt;T&amp;gt;' is the same as 'T', but with each property marked optional.&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nb"&gt;Partial&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]?:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Until now, mapped types could only produce new object types with keys that you provided them; however, lots of the time you want to be able to create new keys, or filter out keys, based on the inputs.&lt;/p&gt;

&lt;p&gt;That's why TypeScript 4.1 allows you to re-map keys in mapped types with a new &lt;code&gt;as&lt;/code&gt; clause.&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;MappedTypeWithNewKeys&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;NewKeyType&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;//            ^^^^^^^^^^^^^&lt;/span&gt;
    &lt;span class="c1"&gt;//            This is the new syntax!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this new &lt;code&gt;as&lt;/code&gt; clause, you can leverage features like template literal types to easily create property names based off of old ones.&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;Getters&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s2"&gt;`get&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Capitalize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&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="nl"&gt;location&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;type&lt;/span&gt; &lt;span class="nx"&gt;LazyPerson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Getters&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="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;and you can even filter out keys by producing &lt;code&gt;never&lt;/code&gt;. That means you don't have to use an extra &lt;code&gt;Omit&lt;/code&gt; helper type in some cases.&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;// Remove the 'kind' property&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RemoveKindField&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="k"&gt;as&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;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&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="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Circle&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;circle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;radius&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;KindlessCircle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RemoveKindField&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Circle&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;// same as&lt;/span&gt;
&lt;span class="c1"&gt;//   type KindlessCircle = {&lt;/span&gt;
&lt;span class="c1"&gt;//       radius: number;&lt;/span&gt;
&lt;span class="c1"&gt;//   };&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information, take a look at &lt;a href="https://github.com/microsoft/TypeScript/pull/40336"&gt;the original pull request over on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Recursive Conditional Types
&lt;/h2&gt;

&lt;p&gt;In JavaScript it's fairly common to see functions that can flatten and build up container types at arbitrary levels. For example, consider the &lt;code&gt;.then()&lt;/code&gt; method on instances of &lt;code&gt;Promise&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;.then(...)&lt;/code&gt; unwraps each promise until it finds a value that's not "promise-like", and passes that value to a callback. There's also a relatively new &lt;code&gt;flat&lt;/code&gt; method on &lt;code&gt;Array&lt;/code&gt;s that can take a depth of how deep to flatten.&lt;/p&gt;

&lt;p&gt;Expressing this in TypeScript's type system was, for all practical intents and purposes, not possible. While there were hacks to achieve this, the types ended up looking very unreasonable.&lt;/p&gt;

&lt;p&gt;That's why TypeScript 4.1 eases some restrictions on conditional types - so that they can model these patterns. In TypeScript 4.1, conditional types can now immediately reference themselves within their branches, making it easier to write recursive type aliases.&lt;/p&gt;

&lt;p&gt;For example, if we wanted to write a type to get the element types of nested arrays, we could write the following &lt;code&gt;deepFlatten&lt;/code&gt; 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;type&lt;/span&gt; &lt;span class="nx"&gt;ElementType&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="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ReadonlyArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;U&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;ElementType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;U&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;T&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;deepFlatten&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;unknown&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;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not implemented&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;// All of these return the type 'number[]':&lt;/span&gt;
&lt;span class="nx"&gt;deepFlatten&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="nx"&gt;deepFlatten&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="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="nx"&gt;deepFlatten&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="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="p"&gt;[[[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]]]]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, in TypeScript 4.1 we can write an &lt;code&gt;Awaited&lt;/code&gt; type to deeply unwrap &lt;code&gt;Promise&lt;/code&gt;s.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Awaited&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="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;PromiseLike&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;U&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;Awaited&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;U&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;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;/// Like `promise.then(...)`, but more accurate in types.&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;customThen&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;U&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;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;onFulfilled&lt;/span&gt;&lt;span class="p"&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;Awaited&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Awaited&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;U&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;Keep in mind that while these recursive types are powerful, but they should be used responsibly and sparingly.&lt;/p&gt;

&lt;p&gt;First off, these types can do a lot of work which means that they can increase type-checking time. Trying to model numbers in the Collatz conjecture or Fibonacci sequence might be fun, but don't ship that in &lt;code&gt;.d.ts&lt;/code&gt; files on npm.&lt;/p&gt;

&lt;p&gt;But apart from being computationally intensive, these types can hit an internal recursion depth limit on sufficiently-complex inputs. When that recursion limit is hit, that results in a compile-time error. In general, it's better not to use these types at all than to write something that fails on more realistic examples.&lt;/p&gt;

&lt;p&gt;See more &lt;a href="https://github.com/microsoft/TypeScript/pull/40002"&gt;at the implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Checked Indexed Accesses (&lt;code&gt;--noUncheckedIndexedAccess&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;TypeScript has a feature called &lt;em&gt;index signatures&lt;/em&gt;. These signatures are a way to signal to the type system that users can access arbitrarily-named 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="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="nl"&gt;path&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;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Extra properties are caught by this index signature.&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propName&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="kr"&gt;string&lt;/span&gt; &lt;span class="o"&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;checkOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;:&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;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
    &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;

    &lt;span class="c1"&gt;// These are all allowed too!&lt;/span&gt;
    &lt;span class="c1"&gt;// They have the type 'string | number'.&lt;/span&gt;
    &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yadda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;opts&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 bar baz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()].&lt;/span&gt;&lt;span class="nx"&gt;toString&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 the above example, &lt;code&gt;Options&lt;/code&gt; has an index signature that says any accessed property that's not already listed should have the type &lt;code&gt;string | number&lt;/code&gt;. This is often convenient for optimistic code that assumes you know what you're doing, but the truth is that most values in JavaScript do not support every potential property name. Most types will not, for example, have a value for a property key created by &lt;code&gt;Math.random()&lt;/code&gt; like in the previous example. For many users, this behavior was undesirable, and felt like it wasn't leveraging the full strict-checking of &lt;code&gt;--strictNullChecks&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's why TypeScript 4.1 ships with a new flag called &lt;code&gt;--noUncheckedIndexedAccess&lt;/code&gt;. Under this new mode, every property access (like &lt;code&gt;foo.bar&lt;/code&gt;) or indexed access (like &lt;code&gt;foo["bar"]&lt;/code&gt;) is considered potentially undefined. That means that in our last example, &lt;code&gt;opts.yadda&lt;/code&gt; will have the type &lt;code&gt;string | number | undefined&lt;/code&gt; as opposed to just &lt;code&gt;string | number&lt;/code&gt;. If you need to access that property, you'll either have to check for its existence first or use a non-null assertion operator (the postfix &lt;code&gt;!&lt;/code&gt; character).&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;// Checking if it's really there first.&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;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yadda&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;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yadda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Basically saying "trust me I know what I'm doing"&lt;/span&gt;
&lt;span class="c1"&gt;// with the '!' non-null assertion operator.&lt;/span&gt;
&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yadda&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One consequence of using &lt;code&gt;--noUncheckedIndexedAccess&lt;/code&gt; is that indexing into an array is also more strictly checked, even in a bounds-checked loop.&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;screamLines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strs&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="c1"&gt;// this will have issues&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;strs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="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;strs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&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;//          ~~~~~~~&lt;/span&gt;
        &lt;span class="c1"&gt;// error! Object is possibly 'undefined'.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't need the indexes, you can iterate over individual elements by using a &lt;code&gt;for&lt;/code&gt;-&lt;code&gt;of&lt;/code&gt; loop or a &lt;code&gt;forEach&lt;/code&gt; 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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;screamLines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strs&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="c1"&gt;// this works fine&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;strs&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;str&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;span class="c1"&gt;// this works fine&lt;/span&gt;
    &lt;span class="nx"&gt;strs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&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;str&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flag can be handy for catching out-of-bounds errors, but it might be noisy for a lot of code, so it is not automatically enabled by the &lt;code&gt;--strict&lt;/code&gt; flag; however, if this feature is interesting to you, you should feel free to try it and determine whether it makes sense for your team's codebase!&lt;/p&gt;

&lt;p&gt;You can learn more &lt;a href="https://github.com/microsoft/TypeScript/pull/39560"&gt;at the implementing pull request&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; &lt;code&gt;paths&lt;/code&gt; without &lt;code&gt;baseUrl&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Using path-mapping is fairly common - often it's to have nicer imports, often it's to simulate monorepo linking behavior.&lt;/p&gt;

&lt;p&gt;Unfortunately, specifying &lt;code&gt;paths&lt;/code&gt; to enable path-mapping required also specifying an option called &lt;code&gt;baseUrl&lt;/code&gt;, which allows bare specifier paths to be reached relative to the &lt;code&gt;baseUrl&lt;/code&gt; too. This also often caused poor paths to be used by auto-imports.&lt;/p&gt;

&lt;p&gt;In TypeScript 4.1, the &lt;code&gt;paths&lt;/code&gt; option can be used without &lt;code&gt;baseUrl&lt;/code&gt;. This helps avoid some of these issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; &lt;code&gt;checkJs&lt;/code&gt; Implies &lt;code&gt;allowJs&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Previously if you were starting a checked JavaScript project, you had to set both &lt;code&gt;allowJs&lt;/code&gt; and &lt;code&gt;checkJs&lt;/code&gt;. This was a slightly annoying bit of friction in the experience, so &lt;code&gt;checkJs&lt;/code&gt; now implies &lt;code&gt;allowJs&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/microsoft/TypeScript/pull/40275"&gt;See more details at the pull request&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; React 17 JSX Factories
&lt;/h2&gt;

&lt;p&gt;TypeScript 4.1 supports React 17's upcoming &lt;code&gt;jsx&lt;/code&gt; and &lt;code&gt;jsxs&lt;/code&gt; factory functions through two new options for the &lt;code&gt;jsx&lt;/code&gt; compiler option:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;react-jsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;react-jsxdev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These options are intended for production and development compiles respectively. Often, the options from one can extend from the other. For example, a &lt;code&gt;tsconfig.json&lt;/code&gt; for production builds might look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./src/tsconfig.json
{
    "compilerOptions": {
        "module": "esnext",
        "target": "es2015",
        "jsx": "react-jsx",
        "strict": true
    },
    "include": [
        "./**/*"
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and one for development builds might look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./src/tsconfig.dev.json
{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "jsx": "react-jsxdev"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information, &lt;a href="https://github.com/microsoft/TypeScript/pull/39199"&gt;check out the corresponding PR&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Editor Support for the JSDoc &lt;code&gt;@see&lt;/code&gt; Tag
&lt;/h2&gt;

&lt;p&gt;The JSDoc tag &lt;code&gt;@see&lt;/code&gt; tag now has better support in editors for TypeScript and JavaScript. This allows you to use functionality like go-to-definition in a dotted name following the tag. For example, going to definition on &lt;code&gt;first&lt;/code&gt; or &lt;code&gt;C&lt;/code&gt; in the JSDoc comment just works in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @filename: first.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// @filename: main.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./first&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @see first.C
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;related&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;Thanks to frequent contributor &lt;a href="https://github.com/Kingwl"&gt;Wenlu Wang&lt;/a&gt; &lt;a href="https://github.com/microsoft/TypeScript/pull/39760"&gt;for implementing this&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Breaking Changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;lib.d.ts&lt;/code&gt; Changes
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;lib.d.ts&lt;/code&gt; may have a set of changed APIs, potentially in part due to how the DOM types are automatically generated. One specific change is that &lt;code&gt;Reflect.enumerate&lt;/code&gt; has been removed, as it was removed from ES2016.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;abstract&lt;/code&gt; Members Can't Be Marked &lt;code&gt;async&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Members marked as &lt;code&gt;abstract&lt;/code&gt; can no longer be marked as &lt;code&gt;async&lt;/code&gt;. The fix here is to remove the &lt;code&gt;async&lt;/code&gt; keyword, since callers are only concerned with the return type.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;any&lt;/code&gt;/&lt;code&gt;unknown&lt;/code&gt; Are Propagated in Falsy Positions
&lt;/h3&gt;

&lt;p&gt;Previously, for an expression like &lt;code&gt;foo &amp;amp;&amp;amp; somethingElse&lt;/code&gt;, the type of &lt;code&gt;foo&lt;/code&gt; was &lt;code&gt;any&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;, the type of the whole that expression would be the type of &lt;code&gt;somethingElse&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, previously the type for &lt;code&gt;x&lt;/code&gt; here was &lt;code&gt;{ someProp: string }&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="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;somethingElse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;someProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;somethingElse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, in TypeScript 4.1, we are more careful about how we determine this type. Since nothing is known about the type on the left side of the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, we propagate &lt;code&gt;any&lt;/code&gt; and &lt;code&gt;unknown&lt;/code&gt; outward instead of the type on the right side.&lt;/p&gt;

&lt;p&gt;The most common pattern we saw of this tended to be when checking compatibility with &lt;code&gt;boolean&lt;/code&gt;s, especially in predicate functions.&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;isThing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;boolean&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;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blah&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&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;Often the appropriate fix is to switch from &lt;code&gt;foo &amp;amp;&amp;amp; someExpression&lt;/code&gt; to &lt;code&gt;!!foo &amp;amp;&amp;amp; someExpression&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;resolve&lt;/code&gt;'s Parameters Are No Longer Optional in &lt;code&gt;Promise&lt;/code&gt;s
&lt;/h3&gt;

&lt;p&gt;When writing code like the following&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;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;doSomethingAsync&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;doSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may get an error like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  resolve()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;error TS2554: Expected 1 arguments, but got 0.&lt;br&gt;
  An argument for 'value' was not provided.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This is because `resolve` no longer has an optional parameter, so by default, it must now be passed a value. Often this catches legitimate bugs with using `Promise`s. The typical fix is to pass it the correct argument, and sometimes to add an explicit type argument.



```ts
new Promise&amp;lt;number&amp;gt;(resolve =&amp;gt; {
    //     ^^^^^^^^
    doSomethingAsync(value =&amp;gt; {
        doSomething();
        resolve(value);
        //      ^^^^^
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;However, sometimes &lt;code&gt;resolve()&lt;/code&gt; really does need to be called without an argument. In these cases, we can give &lt;code&gt;Promise&lt;/code&gt; an explicit &lt;code&gt;void&lt;/code&gt; generic type argument (i.e. write it out as &lt;code&gt;Promise&amp;lt;void&amp;gt;&lt;/code&gt;). This leverages new functionality in TypeScript 4.1 where a potentially-&lt;code&gt;void&lt;/code&gt; trailing parameter can become optional.&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;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&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;resolve&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;//     ^^^^^^&lt;/span&gt;
    &lt;span class="nx"&gt;doSomethingAsync&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;doSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="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;TypeScript 4.1 ships with a quick fix to help fix this break.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conditional Spreads Create Optional Properties
&lt;/h3&gt;

&lt;p&gt;In JavaScript, object spreads (like &lt;code&gt;{ ...foo }&lt;/code&gt;) don't operate over falsy values. So in code like &lt;code&gt;{ ...foo }&lt;/code&gt;, &lt;code&gt;foo&lt;/code&gt; will be skipped over if it's &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Many users take advantage of this to spread in properties "conditionally".&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="nl"&gt;location&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;Animal&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;owner&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;copyOwner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Animal&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;pet&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;otherStuff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// We could also use optional chaining here:&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;copyOwner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Animal&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;pet&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;otherStuff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, if &lt;code&gt;pet&lt;/code&gt; is defined, the properties of &lt;code&gt;pet.owner&lt;/code&gt; will be spread in - otherwise, no properties will be spread into the returned object.&lt;/p&gt;

&lt;p&gt;The return type of &lt;code&gt;copyOwner&lt;/code&gt; was previously a union type based on each spread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ x: number } | { x: number, name: string, age: number, location: string }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This modeled exactly how the operation would occur: if &lt;code&gt;pet&lt;/code&gt; was defined, all the properties from &lt;code&gt;Person&lt;/code&gt; would be present; otherwise, none of them would be defined on the result. It was an all-or-nothing operation.&lt;/p&gt;

&lt;p&gt;However, we've seen this pattern taken to the extreme, with hundreds of spreads in a single object, each spread potentially adding in hundreds or thousands of properties. It turns out that for various reasons, this ends up being extremely expensive, and usually for not much benefit.&lt;/p&gt;

&lt;p&gt;In TypeScript 4.1, the returned type sometimes uses all-optional properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    x: number;
    name?: string;
    age?: number;
    location?: string;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ends up performing better and generally displaying better too.&lt;/p&gt;

&lt;p&gt;For more details, &lt;a href="https://github.com/microsoft/TypeScript/pull/40778"&gt;see the original change&lt;/a&gt;. While this behavior is not entirely consistent right now, we expect a future release will produce cleaner and more predictable results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unmatched parameters are no longer related
&lt;/h3&gt;

&lt;p&gt;TypeScript would previously relate parameters that didn't correspond to each other by relating them to the type &lt;code&gt;any&lt;/code&gt;. With &lt;a href="https://github.com/microsoft/TypeScript/pull/41308"&gt;changes in TypeScript 4.1&lt;/a&gt;, the language now skips this process entirely. This means that some cases of assignability will now fail, but it also means that some cases of overload resolution can fail as well. For example, overload resolution on &lt;code&gt;util.promisify&lt;/code&gt; in Node.js may select a different overload in TypeScript 4.1, sometimes causing new or different errors downstream.&lt;/p&gt;

&lt;p&gt;As a workaround, you may be best using a type assertion to squelch errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;We hope that TypeScript 4.1 makes coding feel perfectly splendid. To stay in the loop on our next version, you can track the &lt;a href="https://github.com/microsoft/TypeScript/issues/41601"&gt;4.2 Iteration Plan&lt;/a&gt; and our &lt;a href="https://github.com/Microsoft/TypeScript/wiki/Roadmap"&gt;Feature Roadmap&lt;/a&gt; as it comes together.&lt;/p&gt;

&lt;p&gt;Happy Hacking!&lt;/p&gt;

&lt;p&gt;- Daniel Rosenwasser and the TypeScript Team&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Type | Treat The Finale</title>
      <dc:creator>Gabrielle Crevecoeur</dc:creator>
      <pubDate>Sat, 31 Oct 2020 18:50:09 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-the-finale-47a4</link>
      <guid>https://forem.com/typescript/type-treat-the-finale-47a4</guid>
      <description>&lt;p&gt;Thank you so much for participating in TypeScript's &lt;code&gt;Type | Treat&lt;/code&gt; coding challenges! Unfortunately, we have come to the end of our spooky journey but no worries, there will be more challenges to come in the future! &lt;/p&gt;

&lt;h2&gt;
  
  
  Beginner/Learner Challenges
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHICcCmoC2BDA1gSwHYHNQ0dCAHE0AdwAssBjK0WyHHRWgFwGdR3JDQAJmnZoARmk6IAUCFCQAZqAA2kWmiWg8VSJy6EcAnlURZ4oeWgBuMeFnbIqaaDi4A6KTLBRohJIyTCuATsxoxKWIgulDT0jMysHNy8RsKCwmISiAA0nvqGAJ4woI6WyESgAIIACgCSoEicJMySmpGI8MKIhvKQZoU+Trzo7HTqSvnuuQDqxsT9oLpo8Ow88PlBPHwCWI1KaPlGDk4uQZxZoPMB4QBe0rIhqfMCzLArGDiQFMWfmzz5JMgQsgSEs0ChEPYzERDAAraC6UDw5AAAyI+WRk1kqJw6OKElAdm4JD2tGyoFE0BWaDiSiUiDQeGgyCQTBQ4IMXRSK3mahwuSRoFgNQ5AA9OQAVf6ITiwX5IFCQUqHQVo2UUOzaSmMRz4DZA3IAcW0umqNQAStKmjgWuwpZNbQDQEadOxTRbGs1kABeUAAbykoFAODBiAAXAt2LZ8AHyaYQgARToAfnDuijeBjAnpCeTqcjQRjoiwkDz6Y8gcczhG+E44Yq8A6+QAPL6eHY6aWgucSPBFZEiKTO-hzio1CNmEOCABfAB8UinHiY1pW212+2dCJ9AAotC7wxvXbV3VbJABKUBemd+mNLziQOmuFR4LfIgByIfDABJfbvdK5g+CU7IqeMZYIoO7GuwrhFssVCJvY563veiCPpAz7IgAQnGVBCPkX4-pB0HYfBiBASBgZgaAEEuq4WbCHBnSIc0yGoeh8YRAI+G-lBdE5vYZE3sxD5Pi+AA6OBYSWoDftxRGQAJgnWixInIuJ9bsBQvQYLWwExrJlYnDWrg9PAACiaD0FuSwaVpF5Xv6gaBquxL7AAEsc1Z4JwVnLJp8AYORoBTiBC65N4Zh4JA6jhvKfZGDs+j5Oc6ohDAKz0EQeAbAebqWp6Ui3iuOwufk7lVqcF5UQZnnhmi56XtegZIcJaEvqAAC0oDiu2YbSb61VBK4IzsHSAlNUJKEqY534DfgqFjsWOBjXESkteh039R5g09n26A4KSAmhUAA"&gt;Investigate haunting data from ghosts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFdQCwIYDcCmoGlQJwJ6gM4AOKAxgJYIA2oh0AtoQNZkB2ANOiwCag4ygB3BCwAuoEZFAksKBCLQYROYqABmWSHVBkRAOgBQ+kKAAqWBFx1lILKpTxFZzFgHMOfWCRiUeXFKtYFcWU0SCxtURQsVQQSFCMwVTDxODR8RGIOACNoMQ90GVAbe1AXSFYXcUlEVBSyfCKWNFoGZzYEgkl8rhsAcjFVFBRqSjJGNB1ehoEwkThQLmhCUZI5CpS0PwCWKxsDfS8WfDEWplZQAF5QAG99UClISjCALlAAIhxhp4F6uDf2+5KYivN5laBYLj-O4EMgALxQIIAsihLPQofcUE0sC4cCCAIwABgAnKAANIAKxoUVAhIJLnRam+URRrxilHwKABMPhAGFESCAKwE3QADlAAA9QAAWYUANgloAAzMKAExSOhQgC+AG5DMYAJJHeQWIqqKQyNaudDBFSjcbPBIdIFoAAK9DOLEuN1AHXuXieWFexywFV9oF0EY6msdxh5wl4-Hy0A5NpQkDNzoaEnNsnk1vwFUoaFGWIA-IZnaA3a1zldhDg9WAAHIocViJYcGQchBYEjzOCQAQJzzx5NBXJkUZKVNVeDCLhFp2pAgIOjNDRZItaH5za2qaAsEgiawsXSgAASg6k8fyrZE5iPGw6MhE4M9lfUmjqDX3h+PNlnFwUDEOY0lXNBnXLA4bGOHM5BQABRcVV2WFBqw9L0AAoAEpLgAPhuaEXzfGh3WcfRo30St0OcAAxDQ6Fog8jxPL1630IA"&gt;Plotting pumpkin types&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHIDcCmoBGjEDtQGt0AcBLDAc1AENQATAsgJwE9RIAzUemW0AF1oIGNsTTj0RkuAKBChaiAM7QANl1mhmkTu2idZIxFwA03ABaJGxTIlpkFCxs2sLQRLpFCSwXIzOR8xiYuoEcgBc3DJisoY8-NgqZBiUoBiQALSyRpAA7rIAdOLuoADC8WwwoAC2ZLjG3tz0eHKgmUb8RqC+WJRyfLxoTMwFnnLIMvJKsgD8+XyQGDphosqgALygANrioKAA3qAKkL5cBLOhAEQAEjCyyACMp4ajilxnImL3C2Khux2U9GcAMscsAAhOinUAAX0h+k2Oz2BzEQLOl2g11AAGZ3o8lC9wlx3q9nnCfn9QKcALJ0FSg2jgqEQmFbXb7Q5IskotEAFixcieuMWBLxX1QVUQlDOhUgkGwQVk7xJZwASuhrrA5ZDIeIALrTWbzaICFSrDZM+Gsk7sq7IABMPLGRNOBuwgpiZ0pxH4dMZcJZiItFytoAA7Ha+WSnS6BGcAMpaPC8a6UOna3VzLhJSDRjLZFbrWHMhFHf0c5AANlDOLJyTS2eTOoKADkssYxKVoKAjGQkMZkFx6nJDB02xVRT3ygVkunKNA8Ap+H5QLBfUWMLByAlF9iuGuUIxUURSAUKNAMEDVOpN7ylGv4okKBhEJknBguJZrnwV3UGlMgA"&gt;Tallying Trick or Treat responses&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEDkHsFpIOwKagNZ0gdwM6nQCwIYAuoAltgOaQlzmjwA0oARgK7ECekLohu1yoTiwBOOSMOQAHADb4AxkgBQIUtgIs4hBABNm7UPlCTI0rcPIIyhAHSgAksWTVthzCznJM15WB+gAmlyikEwAVghyhNjICAiSoBaEhNS0cgQ0OswIfHC6vEiYCoiY9H6YhJDxvGSgAGbCkAC2oASSkghwKXqgjfhONIJBdGERUaDCCPja8NLsfhWg5ZU8fNiYxpDI+kzZ+ABuJOLeioTs7aAASqPi+gC8oADeiqDjkE2YAFyXb40A2gC6z1AaDICE+Bjg7ABigAvooTmckBcfqB7k8XnB8I0EF9ysIUkDpuJwXAWI0dsIgehnBgSWSKUDyLhIOUAPxffCQ2Hwvy4JKSD4gdDC6waBAADxk+GoOnKLFqtWsciawAA4szyphoJztNAAArpCqNTDAABiWK4WoAEvgNFpdVbLWDtbl9bIFFqAKKSdDiXjQCaRG7WPmNaSKZVwcqgOK+4S8K5B4R3R5AlR8wiST4gWN+5nSbSBirJ6zicii5DAXPx3CwAsB67JuvaYAHTAkQitkjxlj4aTQCoiYBAhrvL6-IEvB7ArE40AAIk9mmEnIUoBt0mk88YROE4IArIxqblaV8AEygGGlF5TmfYr7zgAquCQAGkO2kOtvQLvwWejzSWBfAAzJe143tOmL3guer4MI0hBN+v7ngBJ5AaAoFXpOjx3nOT4vhAIiYAgyZIW8e4oTggHgph4G3lBeHPkgACCSQkHIZHEpRx7TOhACMYHYZBs4PkxoAAMqECw2jsJxFGgP+VFoX+gk3jhDEPgAsvg5QkaAABCOijo0cngnxqG8eCAAsqkQbhD6GYWKJnqZ3HUSBl5AoCcLwioz41Mq2gFMyLAFqAci2sR4VNJIJDSHpJENHuii1BokSHHALS2poAAURY3F8ibFuwACUqYvJG0bGai4yNuw1jGZgvzabw1i1Ah4g5S1uANTqTQ5WVABUtVJvVjXWPFNC8CV-wANwjj81hMiyxBovZC4APJhQAUggCoTLJnlwkAA"&gt;Stop a sneaky spooky moving things around&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEHUFNQCwQwG7TqAzpALqA9gM1tgK7qo4B2oKqGATpJqAO4wCWAxjAFAigDmLSUkSxs4ZACYBPShJxtRqFtjJwANqull640nQC01bGwDWLMrwB0nbmAAqrUi1JjK8wjTgZodAA510ZBieShR4oBgw0DBEJDagAEaEWBGQdADkzqCq2Fhh4oQ+quyekOKgbNji0GawqZAANDJlcZJETGLJ2OV0JZThkj7QzOww5USqZb7+kIGgcWLS0cSQVnEAkljZ2MakRcbQKeQa4azmTKwc5fDmkKTxmIz0ZHFLJKBOJ96Y7hQIaoTQMIAA1o7GMAHkaLYehggU04odcCwaNRQD44B4ALaYVI4fBA-wYIzGIEWOZxADCLlahFAyz6vBmqXY-UG4S6mLg+z6QIAEjFIHCMANoHFhpd4JlFOZVMgaLxCNjZrhsDRPqA6BgfqA-qoAXMeMDQSZIdDIJ44WIyod0Vj2aACbciSYgQB+azCtkAMWR1H59IAvKAAN6cUCgcTYVUAOUV9xoAC5QABGADcYfCNDBpphAAoAJRJgBE8SjxiLoAAPqAi6IJJIi+nw4TibmWF5Mahi6XthXq7WrQ3CzrsCxxOmAL7pzie6AAZUgFQk-vQoCDofDkZjcdSSYATE3M9moXnh0WiTkYPEaMQYH2a5izBhUI2My2TG2O12axeItfb-eRaPoEL7Dggo7jpwU4eiKoD2Mi4grtA64ZluNCxpi8ZJgAzIexoQie5oYAWxZ1lIgFwD4hSQIBkZkEkL6Hu+xifpAnakYOFFUbKtHKAxRZgRBk7TrOoBekQNAREha4hqhUboTuiagAALHhWYmoRngkTWZENlWNaoD4ZbSIZY6pIxb5Oq27Zsd+A71oBhnGWgPhmSiAlJuBY7CTBbJzrQ9BYEGADaPoohgSGNAuS6IQKjTwTQsXLI04nuFJAoALrpkAA"&gt;DRY the houses when re-stocking&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Intermediate/Advanced Challenges
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcCdQNYEsAmBnUALAhgNwKaiz4AucAdvilpALaEDuSJmo2oDmkANoQEbYA5gCgQoAGbRu3UJHFZs0yA3z5yobpEgkANG3LUAnjADkBUCWwI1FzIRJJ6FyKFFhaVwuxT40AY1gkAAcHSHU5NmlZeRZ8WgAuYWESQyDCAGVybD8EACFsWAwAXlAAb1dQUCz6eNAAInSuWBJQAGEuPx5sEkJ8wrrhSuxaGHISWoAWQdA-bANDWpJYaHxhAF8klLTQAHFoWgFpYrKKquH8WrqdrXxDXf3D7jQBys7NWEvBYjU60AAfepBOBBXjPaazeaLZarDbJVKEACCQRBvlAJXK02qF3qSJRYNecxQCws0PWm3hbS0yFR6NOWMurSpSF8LxmhOJSxW0zSc2gJDQUK5sK2GXISBy+EKfTRJ0x50umXF1kKoD6rIhRMFq0qPPIfIFJKF5O2ABUtCwgtg0D0ZRjKvT6mbtJhLdb8KzaEgxhzSZUlkqtWS4dsAApqPxIGS0uU1eph8gR7is-05QOwsRQaAzYjdLygNBewS8UBBSOECKKGSxIi+KT8vSEjhzFokFzQNCrMQsJAYVv5nDEWR82yML1i8iCDDDMKCUDGOCIVBoAB0rmDhAASrXuPyAGKwOgACUrylU6hKmWyeQKGABewOldvoFxoP+oEVEqlBTfjMg1KfToWlaNoAvGiZJBmpiDuISCFC0giQIWzhVKo1B9h2lqwLmQ4tnYbLzBIB60COJL4N0aA6G4c4wPhoAoC4LDdKAuBIOwnQGMwSBhIoFjwiuEFgCKz7SK0hLMscy6SVRQkItIJqBDkElSVRskjNaI7EHofDDtwzAkMWJi5JAfB8HcJrYHwoImPh5DaAo5i6vqq6ieQVHzqAHjWGwGg9i0EQauJoAAFbti04iQPAmCOAA-AJvHbLJ3AuSg4kAOrMFwfJhry-IypJy7CEAA"&gt;Sort Trick or Treat loot&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEEkBcHIGdQEYFMkDtQEcCuBLSTQBDdJANzR1QHMAaUWAewFskHUCAbJSUBrHwhw4BYAFAhQkABYEqUhrEjwAnn2jlEKdAGNCkbVMpVQAMwYAnUKqyWTOc4qtJClyqDESEWWJSSxYAHSgACpSenCgqAw8ZGiSMqAA7haOCHjxfHJ0HmDpkDao8Hw8VAwAJvDEZaBlSExsleYEgoygTYLu4mBVRE2RDIlEQrzklgCyxGGQkMQBYjkhCQjmhJRFJlZ8lviETKBh8NrMBFgADkl4UkTogqXml0wLZpa1gkYX0vEEp+YMCFxMIKhJDKIj+JDmHjSHCVDh3B6dCQwr68VAcUGJQigtyJQwGTZYUC6dCvDgfK7SAgw2BYJBzUQLYGgsIaWDcUBnIigDgwngMDZNU4WfDVOQKJTAWr1QrAUoVBY9FnNWAAayQ1RwG2sROIphwwzcjBYvA2lJq3FWHFgCqhS2ikGYiH4-R4BmIVAIlPsRPKdPmXVAAGUZqC2ATLFQsC4yvSxJBlKcCAA1HClUAAXlAAG8xKBIrskAAuUAAIhTaaTYYAEswvOZjAARJD8WAGNBlCwmEs0XOICyoYslsYMDgd0iEEu9qRYJjEcCwKTFyDmWliAC+-vjidAAC0sFgyZmc6I86gC4O9wfu72pWwlyukL22agygAhQjaFXBBhVpBCAAUACUxakAwOBlOum4JsmlAAF4ZtmvZniwg4pqg8EAMIcMK8jXie5rSveq74c+b4fl+P5-hwQEgWBEGiBuDKiFuBAAOI4LBEIIcep7nqW7GceYeF5nKRGPvhhgAFbkcGWIAApYCYJgTKgNGgKB4GQUxLFBjyLCWJmiH4chRaloGekQsJPrYeYg6sU0aAALSgmynpSL8WByFZSDaA6pwcIQsBMDg2hiVpcbQaArHyIo8CZuWDCgAAPru+5kilaGwf6tTaAFfQmFgqC+TgYYLgwn4AIIvsEKynP+YqxcWFXmCsygADxZqAPl+QFQUhWJa4AHzAepdH+sAABUE2gAAArUPw+Xo6qgI58TIsiCCENUW2kCFBATcAYg5XlBAFUVkAlTovz+MCwbtEwsBqRp9FiGdxVhpQ5CKKmS0AEpIEKkL1TFSjFtF4qwAA2gAuoBRl5pqoD-i4SCseUj0NUogFwzxeagBIACqhQ2FSGzIma9xyLa7wOjUDC9nmnjOukRwHtUyTmCqDNEtdsC3cuzgPUB3NNPk5ioL2jG9hINUhSqoJeDwRrcIY1AQGtqAqkkBDEp0jNgGEL5cKiXK6GyjkIMojlmwQm0+Na+GI8jTRNtKGMg7A2Pw3jzxI0chQ8Le6D8qAmOe97eMEWwASke+n7fr+AGAdzjF5lL+ESAA6kg6gEB27BrZU3LRP0iQ9hnYBlWzqDQDwyCSAwiVlJqdjaAekC9k7KMAKK+Qwcm9cF2jAxDXu43mZWVdVtUj7Fyf4Yx6cSAA8gA0nQ0LwOTCTtiaPq1EkeJXMStdEobHpBAsGG6tqiT3PgpiFe9hSaNhgy4iFVyJPqZJcLazQIAYBoBYRwD5HCYKcfUSAAD8EAYDwGwgwFU7wFrTBchCEq3heDOkpE0S+TEJBo3KNyLAn4giyVDOgawEYozmBjEAA"&gt;Bust ghosts to guard Manhattan&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEBEEMDsHMBpQGEDyA1AkuAjATlABaQDOoATgKaQA21AnqAA4CuALqJKAEYCW0AJqAD20UKwIVQ0SK2aVhAMzFkeAYwDWwssqqs+sAHQAoEKACaQud2pCNhEsMasAtBUGshoPsVZVB-T05WMmZoTSFtYN0vaB8-YxMwDFFOEOICMU9GSkZIeQUIsQlQCgA3CmhWRDpLezJ+VSF+NyKKRPIKYmZqVlI+D1bQAHIAFRCwlDIx3QAlTu7eobE6RkkAdwI1DJ5SGkpIfjp2y3YhJX4ZSWcvViHSAFsd4n0OUAUKNaYyIVWyPU6AIRGdpIGCgGrMDprFS+YZjULqSbTGRzLo9YhLAZgoRcABWFFU7FYK0k4hk7R8kDofVExDo0FUoDWPHEgx8KjgNOGwQRSP2rAAyowhIsAPzAxqxInjRFTflCkWkAC8oAA2kZQHDigAFPLqIaIDXDAASlmIkgAxNgDaAjUNTcxzaALQAmA12pARaAUbQCgg-d2aoba6iQVSSM6gADqEXSPEY7oAuhxSJKfMCjMTVqB4RM5bN5ujQCqAN5GzUAIhGOr1FYAXKAy5rm82At6G1whEJqFRoPByy2mf6G+z9P3B82bCKG3NGvUADyjuCIGB0AB8A4AvuPmxWHU6rRXQA2mxPQG2KB2uz2YDuJxshCPgmOBy2p6wZwSIvxF8-lxxoHXLc71APczUtF160bV9WxES9uGvXsQJbB8nw5BAYM1d9PznH8lwQACgJbTcjBIowFFCQkeBEUB7kgdQKBGFBwBQAAKYhhV6BsswoSMeTzZFBU44gAEoG1zWVBNRBZSFPTVKFkMhaWEgxKH4Zhw1Y1jsjKRBVDkShKhE4s12gs8OkU0Q5PM0ADDsnTSmQs9VX0shDNYRMT0wmyLwbBQaHNJybNAbDG23bzzNQ0CKwi5sSPM+K4sQEtNxTHMZT5As0V6ETSOBUwLEhVQwQcngPkGShstIUoeE4CsZlCI9IE7coJREHxMgCYtaPoxjmLY-jJPlYTcrTbsKAMGxYFYjwAly9oYzIdRiEzJohFVKsayWitEwMC9up5Np2j9SxqEERb1FWgINs9JSfVAE7GB2yau3YUsyNMAAxSAeGoFbZvWsDHUtABmZ79pVfy-qO47hV+n1nB2DIfj0EQaDEeNdnkTh3k+ag+E6bgKBsT5xB2W0M0pynTCjPJoH0BsFXhsgVvysBsAMHNNj6XYesYVZ3BJUhshxHt7ip9oXU56sfUkcnODTYIfsqYRRHESQ6P5loeI4MhYGYe4KlYCXTBBznCtAYrREoZxgdeXI-kUQZfFUAh6YAR2YSQFG+e5Bi4ChYD4b1tFdmgezgSRsEyUBYAoIligoAAPMN2AY6k3l99pm3V3WyCpBsCFYVhGGIOsQGaUoDA8YAeOIVQVCcWuSWcKIZGcMPaAqOPnBdZwQegbAADYgA"&gt;Track Trunk or Treat locations&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEE0HsFdQc0gF1AJ0gBwKYBNQEsA7RSURAC01AGNpFMBnZMgQwBtXIB3TTA6yALZZEeEZAIAaUACto2OITgAoEKGyQ4cAJ6gW7Ljz7D+jaAIahmycpWYEC0NqHTMUzbJgB0oJUo9VWV0oAM2gCKjE+fzwPAHVCAkwUAAoAIxQebAAuUEYURSkqSFNzHLzFAEocgG9QAmZS3MR8gjgpADcYzEgy5sVQAF8lTkJ1Tk9ouISk0ABeXMFuxIBRVnpMABFMKi76X1UAeTIpZgjHdh0tGDUYggByZABaBfNxSkw1ygRrEnVSClAoT4qVEnjBKjAABUyDA4GRQFdYFQ7KBOFYqPDRKBxKAAF6QQQ5MiIRDoLIgTiUzzEIQAa0I9HoAEdHBl1HAUGFPEUBMA9BxuLx9mAAJIERiYdxSRF3dqUVKGSz0Wk4UgkCisdCkNisHTQLXMXJFDKpSCuXCQYL-SgCYrICHODDQQIoEyIMwWU7G7D9YjW0C2xiO9DO1ygdKZejeKDQWXy6B4ViIB0wZCGll4Ki0-BCViYcxEKx4HEKgVSVK0fDIDjreikLRYfAEYKQFACIviTzC0AAOS4-qKRAYyDwdcgcpQ0uuwR4rCrdzriNd2FoOj9GWCp2IrvIo4dRQ8atQmEQzEI9cbhBbbY7fGeMrluklKFw5Cs-oALJ4AIzhk+GwgAjkBgHXoRZd1aVEyEzeENXQOsRnIC9+nKSD2wIPAQ0CSIuyUQcgwjHA63mABtAAiAAJGACGwMjQCkMiAGFWwUOiGIABUWNwMLsMiAF0lX4cVk3w5AihKCxSLI9izHQekCDY0BKKQUANg0RSyIAITMVI81ATSeH4wTRN8IEImLPhTwuTisNceJ7CSehkgAfUI7B6ByRAG26K03PoKRnPE91zA8i8fLdD16AqUBqiUUAhKDEYHJQUKACVtlbbAAB5ULaSwCC0AA+OYYqGOLAVbUBklE8MMlVS1QFcur3Oi2L4vi68qpqoKPWxK1ArtSLWvK9qEpHXB5gAAwAEmqNyBkeWaevMAZJupSAABkDBQRjmHWZIKhG9qksSFKSJiAT5kmTB7NOtJmsKQbzEO0ahnisr4oyd0UD4E7HKUMrVBjagUU5SzoLrTAAA8GnQPTz0ymY-XWShOBYawAXoFhGwamw1CsQ0OEgWk61YPAVXLWgHTxjJ6GdZARnYXRmEfFUtAQ6CMUsDJQAFJJkXWXBOswCcdAEPAob62rMny3BlswKQvDgLJu1i1RRrImEwmwR4QzpQgyJqMFPAGCQHQ1rWaMeGFkHZQ2YuN03zfazXqJ1isBF0+VDKNsEnfVl3jQUXXZPk+3qkd534uNh0ypqv6UpKqzdRs0MUFuxz7sjR6JKivDxDAvNPA4OBkgTvOHXYvba2GaYztd7WQ-1hS+M8epzG7ABlLXWCFs9WFr5L6HIvW5MIJux5bzxOg8SAu-QSBEySPBgkzUhMLrUsuBV3xd733fVG-HJoVHcME17sdgitLo9sBNABHxnQAGYpDRmCz8TdypfQDJOhgOtsDMHZmqOe+9VAACZj4AjwLmfMvBTyRFRImOcGQMw8xRJNPak1sQ7k4CQNge1KYM1EPCMCHcA6olbNmREIMjCuBEDqHQq8aL5XyvQbgKB9571UAAWTPAQXUMhoBBncD6SC6YExZhzHDOBhZIhSDAv8d8NDkR8DBv6fckBDzMFNI+RCWs0zODQF7AQO8zKILIUsTAqx1hbB2B4JyTVMi9BaHlAaEkXGVBqHUBomBPGtA6F0HoTRXGDDau1IGDAThMxsOsNQGg6wsEfIaduqNOaYjrLIERT4oYHi8GCZmZAjo1TgLwVKdgKLQxKskegeBcR+LqDpJI0VZjFRIsbAAgigNwWgal1MwBUVu7Z0DJAOnMYqfDyCeGCETFIkyyCeG4uoAQYyABUoBvwADYKjrU7n0VoyQtkVB2dIReBBkh3DuBUAA3EdL60AfoxSOqNVJORSkEHKQQSpUNkjbLNqNUaM9uhvLKRU6GvyXrtSGAMIAA"&gt;Help the annual halloween puppy parade&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEE0HsFcHICcCmoAOBDeAXUkBmo1RNE0BbUAZwGMALRAE2gBsBLAOwHMDRTIA3FsjYsONTABpQAI2jYKkUokhtkaKlRb1EbTGiZMAngCgQoKsoqbESekTo9+g0ACIAKvYByIsaQzIAQoi4kEigAMI08CwUmL4UzkSQ0qqgNHpMkADuiNqgJmC8AoiSmTQstKAs2EjpBpUUbLCYAHRGRuZsMQ5FFK6QAMo0WaAAvKAA3kagqelZOWwAXBOgwfAA0poUS7h6FMgAvuJToMKisX4A8mwAokyk-ZhIiJhL4yshG-RbK7sHR9NDKjQCgABUgQO+b1Wn2+j2gf2OmDoAHUQjFkVVaK93utNks4QjphQmDkUAYABKQfRZbHQvE-Jh7UD7Iz7AgUMwWTBtUzuRB1DiQbBoTJoOqZKo0OzRIjwNB8RAxOpSRBUNDA5AGGAzBWUBTIAAGaDYBgNHPYdmQ+U5WikaCZqzMNUw7C4SOQ1DojBJ8GaoAAgmxQBc1mZ0jjuLgWPAuugKBRJDJuaZsggPWkopwbcgJUicO6YwQ2LZRTpEslQIgAB4oVgaFptXDQNhUF3KHhoADWiH6tAYzGsAApCoJYQYUEp8CPFX1BlkAJRLY11SbTDpdT39kmjCZs+1F4zTR2D9fYaeVIMXKQAK1VLW7Bgow8civn84mxzXXLDKCqeg8ZDIGM07NLQGD+pgg4AAzzs0mCQAAqigE7wGE9qIIO74ANTdIIzTEuUGEAIzzgA3G00xEn23qIAA2gaHDPAAauS-QAGIhAAJOMaq-roTAAYo+wGgAujumGjAAfLun6UNRA70b43Zgig5jwGwHHwNxvF-gJgHCWJYwSSM0njCylFyV6CkGrWYraWgfH-vponie+JkydMLLHEgmDQOpllbogrI8mAYTOoq3CbjR8DtN+05eGcO5KT28k+s+PSzkMmTziFoB8kG4bug6zatiwFgEKE6rwb4LpqvodRUOFthGPF3gtIxmAsexITkrM2TaJhLUvglYjNMlKlqRpPV9fMg2tWczS2RSM0DTl1oeEK3BpNS-VBtOACEeVlByFBDMwtgqtw5ikL+PqVvA8AhENRQje1zGsZpr2+EggSrIgERRDEcRzcNbVjV2iATSEU3wF9fi-SE-2RNE5xPjl82jUtcM-UEiMAyjwNrRjb2dR9PXgsCYIQiDL1g+NkCqdDmmUhCVPAjTgivYtTBiizlMU2jbS5f0KCQCwPocsatjoFgoAAEw4PgSIymB+jaIxFXICqGSZELetC6YYRMPCoBEX67gq9tJKcFr0Di18itK-YPNdMoxSgKU5RSjI9scnguDWu6oAu9gbuSM8VDNFH+t64bxvIHL5t0EyMSZhwhhEOODArCVbZBmwgEcmqQYoI9dpSBnl1pMWJLNSmkrcComQrCQvmhLgj3kK4We9lEKDYAALM0RExzHpgAFTjyCGDYJgmSQJPuVQNAOrIEH5haOWIQcMaLAAF5r-YFCAQFNGJrIHsN8oGedpsuGKq0pgAJKYLAF3IBwzqVPgWor+Y50EGQhnIOx9FCZwnByAAtNIC+19xR0AKvfa0aQOQqlyFoKgPMbDlkuoQW+DsQJCybC2POHZuyfF7FZNK04xwTjwPfXoAwsqLgPB+L8nQ5CpSArudkB5jjHlPPfQSyB6FXlvK2ZoD4nw0LfGwyipgAACmAKCQJEGwRGslBHnmAi+Rhc5Mi0XioBESskWD4HSnhOkXx3yrgspyDhP5dLCKSsNQCoEMwQWgrBeCSEUJoT2BJHCRjFD4TrMRMiFE7FRWsh1Lqml7KOT0kJFyRk3KmXMlErhikIZQ3UvEniDknHOUMqAYy6TZJUSoXRGyPMDAJKKckkpZSPKUQyV5aYPk-JBmiSSYK1p8oewQR7ZAaRdTGhwDeO8gyvagA1ByIqa8s4UFig4-BFAACyoNErAQhhQrh8ALEziYQuYWZ0mC2B2OLIwazNm0wWrEsm8Beo7VmjlG5WzMa1OeTrV5pyYDnNQPaZZ7y7mjQed1J5As2aCxBZzOmOSGaTWZlCgWg1YWIC5ktPmoJUVrQNmAEWYs7qYPhKgxAOtR7WjNhAbUxdQBIEgRqUAv94BEEQDdHmxBg5VGsHocBipz7YF-icHIthCBNw7MhbOmAs6tEpdaROoA2LsHoK6S09K2qUFFtgR0LL7GqrznymUjxyidgMIKy0lUkCNFnpAJIvgTSoEgJYPOyzTCUVKNYTUtLxlMvdKQOVlLTAAGY-TLw7HUFQ0qkgOVrHUNA9ADVlQLkwexjw0DsGUeWPVvgpW2BlROFYnd1VRhjKHFQRggA"&gt;Put on a horror movie marathon&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;Like many challenges, you answer to this depends on how thorough you wanted to type the houses. &lt;br&gt;
The in-challenge text tries to guide you to answer with a single generic type which passes the first argument to both &lt;code&gt;trickOrTreat&lt;/code&gt; and &lt;code&gt;restock&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;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Candy&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;doorNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;trickOrTreat&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Candy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;restock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Candy&lt;/span&gt;&lt;span class="p"&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FirstHouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;book&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;candy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SecondHouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toothbrush&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mints&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// ... same pattern for the rest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could be enough, and that's totally enough type safety for cases like this. This does lose the &lt;code&gt;doorNumber&lt;/code&gt; being exact though. So, here are two different routes to give the &lt;code&gt;doorNumber&lt;/code&gt; to each house:&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;// Via a 2nd generic argument&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DoorNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Candy&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;doorNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DoorNumber&lt;/span&gt;
  &lt;span class="nx"&gt;trickOrTreat&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Candy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;restock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Candy&lt;/span&gt;&lt;span class="p"&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FirstHouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;book&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;candy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SecondHouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toothbrush&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mints&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// ... same pattern for the rest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&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;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Candy&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;doorNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;trickOrTreat&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Candy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;restock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Candy&lt;/span&gt;&lt;span class="p"&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;// Via intersection types:&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FirstHouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;book&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;candy&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;doorNumber&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SecondHouse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toothbrush&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mints&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;doorNumber&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEHUFNQCwQwG7TqAzpALqA9gM1tgK7qo4B2oKqGATpJqAO4wCWAxjAFAigDmLSUkSxs4ZACYBPShJxtRqFtjJwANqull640nQC01bGwDWLMrwB0nbmAAqrUi1JjK8wjTgZodAA510ZBieShR4oBgw0DBEJDagAEaEWBGQdADkzqCq2Fhh4oQ+quyekOKgbNji0GawqZAANDJlcZJETGLJ2OV0JZThkj7QzOww5USqZb7+kIGgcWLS0cSQVnEAkljZ2MakRcbQKeQa4azmTKwc5fDmkKTxmIz0ZHFLJKBOJ96Y7hQIaoTQMIAA1o7GMAHkaLYehggU04odcCwaNRQD44B4ALaYVI4fBA-wYIzGIEWOZxADCLlahFAyz6vBmqXY-UG4S6mLg+z6QIAEjFIHCMANoHFhpd4JlFOZVMgaLxCNjZrhsDRPqA6BgfqA-qoAXMeMDQSZIdDIJ44WIyod0Vj2aACbciSYgQB+azCtn85YAHgAIthVQA5RX3GiNKkSSQAPlAAF5QABvTigUDiQM0EOYsMALlAAeDodSKfCNDBpphAAoAJR5yNSADcJcJxMrLC8mNQdatklrOuwLHETYAvh6RaAAGLI6je9Dx0CzyA+gCMjQARPFA8Y16AAD6gNeiKNr6NjtkAZUgFQki-ni59ACZ10ScjB4jRiDAd-u15izBhUBPM9oHsZFxFvBN7wAZnXI8pG-A84B8QpIAQtd0zIJJANPThPWgCciBoCIIIXAUfQAFlgns0NQHwt2kWjB1SbDgNAc9aHoLAEwAbSnFEMEXRpL2vcCBUaUCaFE5ZGgI9xiIFABdJsgA"&gt;Our answer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;OK, this one is tricky. It's based on &lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-dev.20201028&amp;amp;q=248#example/mapped-types-with-template-literals"&gt;this Playground example&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;We started out by making types for passing the data around&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;Movies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;moviesToShow&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Movie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;forKids&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="c1"&gt;// Template strings literals to describe each task&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;getVHSFor&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;capitalize&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;MakePopcorn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;makePopcornFor&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;capitalize&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Play&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="err"&gt;play&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;capitalize&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

&lt;span class="c1"&gt;// A union of the above literal types&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Tasks&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&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;Get&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="nx"&gt;MakePopcorn&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="nx"&gt;Play&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These gave us a set of primitives which could work together to create this whopper:&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;MakeScheduler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Type&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Tasks&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Field&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;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type uses the new &lt;code&gt;as&lt;/code&gt; syntax for mapped types in TypeScript 4.1 to essentially map each field (Field) from the keys in the input type (Type) to the union &lt;code&gt;Tasks&lt;/code&gt; above. This means that each field is converted into three templated literals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;input: &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="s2"&gt;"halloween"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; turns to:
  ├─ Get&amp;lt;&lt;span class="s2"&gt;"halloween"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; -&amp;gt; &lt;span class="sb"&gt;`&lt;/span&gt;getVHSForHalloween&lt;span class="sb"&gt;`&lt;/span&gt;
  ├─ MakePopcorn&amp;lt;&lt;span class="s2"&gt;"halloween"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; -&amp;gt; &lt;span class="sb"&gt;`&lt;/span&gt;makePopcornForHalloween&lt;span class="sb"&gt;`&lt;/span&gt;
  └─ Play&amp;lt;&lt;span class="s2"&gt;"halloween"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; -&amp;gt; &lt;span class="sb"&gt;`&lt;/span&gt;playHalloween&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is declared to be a function which returns void.&lt;/p&gt;

&lt;p&gt;This type is then used as the return type for the &lt;code&gt;makeScheduler&lt;/code&gt; 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;makeScheduler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Movies&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;MakeScheduler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Movies&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;For simplicities sake, we skipped typing the inside of the function - though the folks who did that, good work!&lt;/p&gt;

&lt;p&gt;The second part added one simple constraint, but one that requires some work to get right. We wanted to take into account whether a movie was for kids of not &lt;em&gt;inside the type system&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Our answer for this was to recreate the scheduler function above, and to add the logic for removing those types during the type mapping process.&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;MakeKidsScheduler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Type&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Tasks&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Field&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;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;forKids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;  &lt;span class="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="nx"&gt;never&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;Instead of returning a &lt;code&gt;() =&amp;gt; void&lt;/code&gt;, we inserted a conditional type in the return position which first checked if &lt;code&gt;forKids&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt; in the original type. If it was, then it returned the function - otherwise it returned &lt;code&gt;never&lt;/code&gt;. Returning never here would mean that the function would not exist - removing them from the mapping process.&lt;/p&gt;

&lt;p&gt;The community came up with quite a few alternative takes which provided type safety inside the functions and used different routes like &lt;a href="https://twitter.com/danvdk/status/1322546300617969664"&gt;removing the non-kids movie&lt;/a&gt; &lt;a href="https://twitter.com/RickLoveToldMe/status/1322321114132086784"&gt;keys ahead of time&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEE0HsFcHICcCmoAOBDeAXUkBmo1RNE0BbUAZwGMALRAE2gBsBLAOwHMDRTIA3FsjYsONTABpQAI2jYKkUokhtkaKlRb1EbTGiZMAngCgQoKsoqbESekTo9+g0ACIAKvYByIsaQzIAQoi4kEigAMI08CwUmL4UzkSQ0qqgNHpMkADuiNqgJmC8AoiSmTQstKAs2EjpBpUUbLCYAHRGRuZsMQ5FFK6QAMo0WaAAvKAA3kagqelZOWwAXBOgwfAA0poUS7h6FMgAvuJToMKisX4A8mwAokyk-ZhIiJhL4yshG-RbK7sHR9NDKjQCgABUgQO+b1Wn2+j2gf2OmDoAHUQjFkVVaK93utNks4QjphQmDkUAYABKQfRZbHQvE-Jh7UD7Iz7AgUMwWTBtUzuRB1DiQbBoTJoOqZKo0OzRIjwNB8RAxOpSRBUNDA5AGGAzBWUBTIAAGaDYBgNHPYdmQ+U5WikaCZqzMNUw7C4SOQ1DojBJ8GaoAAgmxQBc1mZ0jjuLgWPAuugKBRJDJuaZsggPWkopwbcgJUicO6YwQ2LZRTpEslQIgAB4oVgaFptTAGFDIACyjkVoyIzaU+EKgl6AyGmSMTZboHbRS7UI+9KkkCpJCDLLHbY7HjIyDGAGt+XgJx2KABuHlgVyIUi1tDESiPV0c1jEOWM8taahRFWVtRS3QUbejntQAAcWeAAeVxKyrYhiw5GJMw4AA+LtQANDhngANXJfoADEQgAEnGNUUCqPQWAAL2QVx9gNADx1bNBdzBFBzHgNhwMg6CvlveCkLGFDfEYyBmJCNhcPgAiiJI1gKNAKiaNXUAQSYMV2OrTjYLvTheOmA0rwMCS0GI3RpMo5kaOtf1QGgYRlBwfB3QIeddUfaw9G7FsKFoyj7W3ChVKg7QuLg11tJAzBwKQgAfCcGMQJiWLY1wosU5SDAixtAPo3d+loBhmGscCe20yZpgAbWwwQmFsC1dy1fBXEA+1ZJ8vyKsQKqOMCjT4NAAB+UA2o6pYVAVeAEIAXSWUAAAoAEpRiQvhIE0E99hPIxcGsqgXVsgTEByr18vgab+0VJZJwHWbztig68p9UCLsVJCSs5To5Fy70twmNkmuNYxpkdaaOi6U67ODKQACtVRaWqKBOw9Zvml7pmmYHsEk4yN0ULtTuaWgMH9TBpoABlm5pMEgABVFAW3gMJ7UQObQAAam6QRmmJcpGYARlm9aUZRz07sQUrUIwrCxIMoy9CxxBqPGrsmZGZ6WQFokPvy0W9vikTJcIwypNl+XFfm5XvuOAWhc+0W9Klw3N2NsYlZV44WWOJBMGgVjKA1klWVPcJnU7QgraO9ouTZxAvDOHGbt96x4Z6PpBiyWaA75INw3dB0tp2zoCFCdUKd8F01X0OoqCD2wjFO6OxGaNDMEwnCQnJWZsm0Oaa-XbwWm1oSErEtvqQ7tgu9r3vmj04eMlHrvrQ8IVuDSEf5kjgBCWSylgoZmFsT9CHMS8WB9St4HgEJu6KOuWkb5uxJv3wkECVZEAiKIYjicee7OZp++E1iD9e5P0QC-EIb9IjRHOHDNOE9f56Ufn4MBSB35QK-mnK+ggb4N3Fi3eAlIIRgghN-a+k9-6D1buCYERDgQkKwZPaeVDQRMPngHfoKBlo+g5MaWw6AsCgAAExgyRDKfG+htBoQLsgFUs82hyPkdaMITB4SgG5n6dwoiV4kk4NI6AJ8uJ4HsvYZSXRlDFFAKUcoUoZD6I5IY60DkTHYDMZIZ4VBmgeIUfI0wSiVECPUXQJkwVOCGHcgwFYucWC2TYJuDkaogwoAvnaKQoTPxpGLCSauKZJTcBUJkFYJBPahFwBfcgDUWw5SiCgbAAAWZo3MvFeNMAAKmaSCDA2BMCZEgK0gOUBoA6mQA5cwWhywhA4MaciQz7AUE3D7Q6JJEyyAsTk5QoTtybEjhQVopgACSmBYD72QBwZ0lR8BagGeYPeBAaahIcrM7Gq4OQAFppDLLWeKOgmdI7WjSByFUuQtBUGUjYcsB9QAbK4rjORCksqIBhLdT68BCotmKsccqlVqpBlqvucpqgOSuBaqBQatg1JdW4q6PqA1MWgGGogUaE0poW1kj2DF7V6AKzJTBZYdIvj4ngCotk-UZqm0WstWwdLRqrXWptNg20olBj2p8RFR1E4DnOgja6u4EXx2Raufcp1Bwp0yM9Y4aN5nC2nD9bhJp+YRiBhHUG+4LiQ2hs0WGarFSIwmMy0wAABTAFBnkiDYOA5lLB8CeqNcOUqp1xrNF5RQJGzLUYRwxjLOZYxcb43gITEmZMKbU1pvTPYTNWa405lQHmfM2hqwtdbMWTcJb4X1tLJgRsDQKydqK82dbQ4ki1rFHWgCW3pvbQ7TtJsFq9rVv2kWulUp20xhOrtIrp3jFVnW5krt5HTA9l7IMc72QxW1ZsFV919V9kPMnYcCF-bWgzhYr5FjkBpF1MaHArrtpPqsVZPYHJs5DJ7J5c1kKKCPRvrHU99Bz0J0NTe1ObDd4dR2CfIwYGIOTzvs2-B7d5hdwwz-eu088OdwwaYFO1y4yeUI6Q3+2G8EEOoSwtOtH6G-3IbrShhCWPoc2Jh+BqUmPMOIRguRFGOEn2sGYZRnYZFZEadaNREBtTxNAEgZ5GpQAXPgEQC8V4bwuWfGEhMbzsAXJODkWwhA8k8EMi2Wwq5WiKetP46lxZKUOSiDHCgHDsCOh069egVQFVuRlHeKg24DBLM6XQQuSBGidIXHZk0qBICWDzp5UwKNSjWE1Kpj9Wn3SkGc4p0wABmP0-S7N1BUOEimNzax1DQPQYLec3IdEeGgdggbyyBd8DTergESkKEtCsaMpiVBGCAA"&gt;Our answer&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Share Your Experience
&lt;/h2&gt;

&lt;p&gt;We would love to hear your feedback on this weeks challenges whether good or a bad! If you can please take our quick 4 question survey that can be found &lt;a href="https://www.surveymonkey.com/r/FSQ7DLC"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want More?!
&lt;/h2&gt;

&lt;p&gt;If you want to learn more about TypeScript, check out some of our best resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/play?target=1&amp;amp;q=326#example/hello-world"&gt;The TypeScript Playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/typescript/"&gt;The TypeScript Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>challenge</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Type | Treat Challenge 5

</title>
      <dc:creator>Gabrielle Crevecoeur</dc:creator>
      <pubDate>Fri, 30 Oct 2020 21:06:05 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-challenge-5-40n4</link>
      <guid>https://forem.com/typescript/type-treat-challenge-5-40n4</guid>
      <description>&lt;p&gt;Welcome to the final Type | Treat challenge! Today we will be restocking Halloween candy and identifying Halloween movies&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;We were looking for using the &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype"&gt;&lt;code&gt;Readonly&lt;/code&gt;&lt;/a&gt; utility type to force the type to not allow poltergeists to make changes to your rooms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- type Rectory = {
&lt;/span&gt;&lt;span class="gi"&gt;+ type Rectory = Readonly&amp;lt;{
&lt;/span&gt;    rooms: Room[]
    noises: any[]
&lt;span class="gd"&gt;- }
&lt;/span&gt;&lt;span class="gi"&gt;+ }&amp;gt;
&lt;/span&gt;
- type Room = {
&lt;span class="gi"&gt;+ type Room = Readonly&amp;lt;{
&lt;/span&gt;    name: string
    doors: number
    windows: number
    ghost?: any
&lt;span class="gd"&gt;- }
&lt;/span&gt;&lt;span class="gi"&gt;+ }&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's worth remembering that JavaScript doesn't have immutability like this, so this really only affects the type system. You'll get a compiler error, but people can still work around that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEDkHsFpIOwKagNZ0gdwM6nQCwIYAuoAltgOaQlzmjwA0oARgK7ECekLohu1yoTiwBOOSMOQAHADb4AxkgBQIUtgIs4hBABNm7UPlCTI0rcPIIyhAHSgAksWTVthzCznJM15WB+gAmlyikEwAVghyhNjICAiSoBaEhNS0cgQ0OswIfHC6vEiYCoiY9H6YhJDxvGSgAGbCkAC2oASSkghwKXqgjfhONIJBdGERUaDCCPja8NLsfhWg5ZU8fNiYxpDI+kzZ+ABuJOLeioTs7aAASqPi+gC8l5PTcLMAPADeiqDjkE2YAFyXH6NADaAF1PqA0GQEP8DHB2GDFABfAB8ihOZyQFyBoHuVymM3Y7whcHwjQQAPKwhSEOm4lhcBYjR2wgh6GcGAZTJZEPIuEg5QA-AD8PDkWj0SpcElJH8QOgFdYNAgAB4yfDUHTlFi1WrWORNYAAcX55Uw0FF2mgAAV0hVGphgAAxMlcc0ACXwGi0VvdbphFtyNtkCnNAFFJOhxLxoBNIjdrNLGtJFAa4OVQHEo8JeFd48I7qAPl8pTL-iAs9H+dJtHGKgXrOJyErkMBKzncLAa7HrgWu9pgAdMCRCIOSDmWPhpNAKiJgBCGr8AcCIV83pCyRTQAAiMOaYSihSgT3SaTbxh04SwgCsjHZuU5AIATKAkaUvmuN+SAduACq4JAAGkRzSDpz1AS9YSfO8OSwAEAGZX3fD911Jb8d2tfBhGkIJwMg58YIfODQEQt9VyLL8tz-ACIBETAEALPCfivAicFg2FSOQz80Ko-8kAAQSSEg5CY+lWPvaZiIARiQ8jUM3H8+NAABlQgWG0dhRJY0BoLYoioNkj8KJ4n8AFl8HKBjQAAIR0RdGi02EpMIyTYQAFkMlDKJ-WzaxxJ9HPE9iENfCFwSRdE-H-GoDW0Ap+RYGtQDkL16OSppJBIaQrIYhor0UWoNEiQ44BaL1NAACjrG4ATzet2AASiLCE0wzezcXGXt2GsezMGBczeGsWocPECqBtwHrLSaCqmoAKk6-Nut66xspoXgGtBABuBcgWsPkBWIe55PQ7cAHkkoAKQQXUJk00KIqAA"&gt;Our answer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;This challenge evolved quite naturally from the third challenge with the addition of 4.1's heading feature Template Literals.&lt;/p&gt;

&lt;p&gt;The most elegant answer moved the return type into the object &lt;code&gt;const winners&lt;/code&gt; which would then be inferred as the return type of &lt;code&gt;tallyPopularWinners&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const breeds = ["Hound" , "Corgi" , "Pomeranian"] as const
const costumes = ["Pumpkin" , "Hot Dog" , "Bumble Bee"] as const
&lt;/span&gt;
+ type Breed = typeof breeds[number]
&lt;span class="gi"&gt;+ type Costume = typeof costumes[number]
+ type BreedCostumeCombination = `${lowercase typeof breeds[number]}-${lowercase typeof costumes[number]}`
&lt;/span&gt;
function tallyPopularWinners(_breeds: typeof breeds, _costumes: typeof costumes) {
&lt;span class="gd"&gt;-  const winners = {} as any
&lt;/span&gt;&lt;span class="gi"&gt;+  const winners: Record&amp;lt;BreedCostumeCombination, ReturnType&amp;lt;typeof decideWinner&amp;gt;&amp;gt; = {} as any
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEE0HsFdQc0gF1AJ0gBwKYBNQEsA7RSURAC01AGNpFMBnZMgQwBtXIB3TTA6yALZZEeEZAIAaUACto2OITgAoEKGyQ4cAJ6gW7Ljz7D+jaAIahmycpWYEC0NqHTMUzbJgB0oJUo9VWV0oAM2gCKjE+fzwPAHVCAkwUAAoAIxQebAAuUEYURSkqSFNzHLzFAEocgG9QAmZS3MR8gjgpADcYzEgy5sVQAF8lTkJ1Tk9ouISk0ABeXMFuxIBRVnpMABFMKi76X1UAeTIpZgjHdh0tGDUYggByZABaBfNxSkw1ygRrEnVSClAoT4qVEnjBKjAABUyDA4GRQFdYFQ7KBOFYqPDRKBxKAAF6QQQ5MiIRDoLIgTiUzzEIQAa0I9HoAEdHBl1HAUGFPEUBMA9BxuLx9mAAJIERiYdxSRF3dqUVKGSz0Wk4UgkCisdCkNisHTQLXMXJFDKpSCuXCQYL-SgCYrICHODDQQIoEyIMwWU7G7D9YjW0C2xiO9DO1ygdKZejeKDQWXy6B4ViIB0wZCGll4Ki0-BCViYcxEKx4HEKgVSVK0fDIDjreikLRYfAEYKQFACIviTzC0AAOS4-qKRAYyDwdcgcpQ0uuwR4rCrdzriNd2FoOj9GWCp2IrvIo4dRQ8atQmEQzEI9cbhBbbY7fGeMrluklKFw5Cs-oALJ4AIzhk+GwgAjkBgHXoRZd1aVEyEzeENXQOsRnIC9+nKSD2wIPAQ0CSIuyUQcgwjHA63mABtAAiAAJGACGwMjQCkMiAGFWwUOiGIABUWNwMLsMiAF0lX4cVk3w5AihKCxSLI9izHQekCDY0BKKQUANg0RSyIAITMVI81ATSeH4wTRN8RAG0oTSMlVeYzKwS1wys7B6BIhwBAVFA+KUWzKGYiS5gvborXE91zGc1z3M87z9Mc3yQswZi3MIW9-IAAwAEmqAUkmRdYAvswinJcnSkj4gZHgyrKUByyhvPs4KPTC4qPIGFLfCBCJiz4U8Lk4rDXHiewknoZIAH0CvoHJaqtcapBG+rQsm8y6rtBqKlAaolFAISgxGQaUAm0AACVtlbbAAB5LMyWKPQSkF6kiKRjvdFACEhcyzqmtRti6AbEhQAA+f7-OqAZBLsLRfC269QGSUSHMybErTGxz6DWjatqh1sYbh+bKHsuaVtCtHNoxra4ZiVKMoKsqMtxlrqUgAAZAwUEY5h1mSNb2eiq7CfiwQ7tvEnSd2v7nJiAT5kmTBfqSNJHMKPmKmFwYSaGEmMmevhRaGpR1dUGNqBRTkuugutMAADwadA9PPU6Zj9dZKE4FhrABegWEbeybDUKxDQ4SBaTrVg8BVctaAdH2MnoZ1kBGdhdGYR8VS0BDoIxSwMlASrqtwaHMAnHQBDwC3Efh1U7FwXGpC8OAsm7DbVFJsiYTCbBHhDOlCDImowU8AYJAdZvW5ox4YWQdke-WvuB6HjGW+o9uKzcvSFUwKfqhnwem-n40FA72T5I3me562vuHXVuGdf2-zut1XrQxQWX9vlyNFYk1G8PEMC808Dg4GSNfT+Dp2Ls1rMMaY+1yIj3bp3OS3c+KeHqOYbsABlVurA85nlYBAvazkyJwPkgfLuClEGdA8JANB6BICJiSHgYImZSCYTrKWLg9dfAcM4Rw1Q34cjQlHOGBMmCxzBCtF0bmwQ0ACF9joAAzFIF2MFBGJicmXdAGROgwDrNgZgqc1SUK4aoAATHwgEeBcz5l4KeSIqJExzgyBmLOKIUrsxStiHcnASBsHZuHOOoh4RgRQTvVErZsyIiNkYVwIgdQ6AYTRSwfA7D0G4CgLhnDVAAFkzwEF1DIaAQZ3A+kgumBMWYcw20sYWB6Cx-jvnCciPgJt-T7kgIeZgppHyIVbmmZwaBdL5nYe1GxgSliYFWOsLYOwPDDWRpkXoLQ2igAJhJeZlQah1AaJgVZrQOhdB6E0BZgx0YYwNgwE4CcbC5XZHWFgj5DTIOdunTEdZZAFKfBbA8XgwSJzICrOGcBeCHTsBRS2-lkj0DwLiLZdQmprVmEDEifcACCKA3BaHBZCzAFREHtnQMkTmcwgZZPIJ4YIAcUjErIJ4bi6gBAEoAFSgG-AANgqAzVBfRWjJBZRUNl0gaEEGSHcO4FQADcKtNbQBeutFWpMHk5ABQQIFBAQUW2SKywepNSbkO6AqwFwLLbquVqTIYAwgA"&gt;Our answer&lt;/a&gt; Also, we watched the full two hours of that video, and it's a great background video while you're working.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;You're in charge of restocking the houses on your street, can you find a way to reduce the duplication in your notes by generically declaring a house?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEHUFNQCwQwG7TqAzpALqA9gM1tgK7qo4B2oKqGATpJqAO4wCWAxjAFAigDmLSUkSxs4ZACYBPShJxtRqFtjJwANqull640nQC01bGwDWLMrwB0nbmAAqrUi1JjK8wjTgZodAA510ZBieShR4oBgw0DBEJDagAEaEWBGQdADkzqCq2Fhh4oQ+quyekOKgbNji0GawqZAANDJlcZJETGLJ2OV0JZThkj7QzOww5USqZb7+kIGgcWLS0cSQVnEAkljZ2MakRcbQKeQa4azmTKwc5fDmkKTxmIz0ZHFLJKBOJ96Y7hQIaoTQMIAA1o7GMAHkaLYehggU04odcCwaNRQD44B4ALaYVI4fBA-wYIzGIEWOZxADCLlahFAyz6vBmqXY-UG4S6mLg+z6QIAEjFIHCMANoHFhpd4JlFOZVMgaLxCNjZrhsDRPqA6BgfqA-qoAXMeMDQSZIdDIJ44WIyod0Vj2aACbciSYgQB+azCtkAMWR1H59IAvKAAN6cUCgcTYVUAOUV9xoAC5QABGADcYfCNDBpphAAoAJRJgBE8SjxiLoAAPqAi6IJJIi+nw4TibmWF5Mahi6XthXq7WrQ3CzrsCxxOmAL7pzie6AAZUgFQk-vQoCDofDkZjcdSSYATE3M9moXnh0WiTkYPEaMQYH2a5izBhUI2My2TG2O12axeItfb-eRaPoEL7Dggo7jpwU4eiKoD2Mi4grtA64ZluNCxpi8ZJgAzIexoQie5oYAWxZ1lIgFwD4hSQIBkZkEkL6Hu+xifpAnakYOFFUbKtHKAxRZgRBk7TrOoBekQNAREha4hqhUboTuiagAALHhWYmoRngkTWZENlWNaoD4ZbSIZY6pIxb5Oq27Zsd+A71oBhnGWgPhmSiAlJuBY7CTBbJzrQ9BYEGADaPoohgSGNAuS6IQKjTwTQsXLI04nuFJAoALrpkAA"&gt;Help keep those houses DRY&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;You're working on a horror movie night. You've skipped the types because you figured it'd be simple to work with but someone put the wrong movie in and The Nightmare Before Christmas is not a halloween movie. &lt;em&gt;It's in the name&lt;/em&gt;. Anyway. To avoid this happening again, you figure it's time to add types to the function. Once, you got that down then you wonder if you can do the same thing for the kids schedule?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEE0HsFcHICcCmoAOBDeAXUkBmo1RNE0BbUAZwGMALRAE2gBsBLAOwHMDRTIA3FsjYsONTABpQAI2jYKkUokhtkaKlRb1EbTGiZMAngCgQoKsoqbESekTo9+g0ACIAKvYByIsaQzIAQoi4kEigAMI08CwUmL4UzkSQ0qqgNHpMkADuiNqgJmC8AoiSmTQstKAs2EjpBpUUbLCYAHRGRuZsMQ5FFK6QAMo0WaAAvKAA3kagqelZOWwAXBOgwfAA0poUS7h6FMgAvuJToMKisX4A8mwAokyk-ZhIiJhL4yshG-RbK7sHR9NDKjQCgABUgQO+b1Wn2+j2gf2OmDoAHUQjFkVVaK93utNks4QjphQmDkUAYABKQfRZbHQvE-Jh7UD7Iz7AgUMwWTBtUzuRB1DiQbBoTJoOqZKo0OzRIjwNB8RAxOpSRBUNDA5AGGAzBWUBTIAAGaDYBgNHPYdmQ+U5WikaCZqzMNUw7C4SOQ1DojBJ8GaoAAgmxQBc1mZ0jjuLgWPAuugKBRJDJuaZsggPWkopwbcgJUicO6YwQ2LZRTpEslQIgAB4oVgaFptXDQNhUF3KHhoADWiH6tAYzGsAApCoJYQYUEp8CPFX1BlkAJRLY11SbTDpdT39kmjCZs+1F4zTR2D9fYaeVIMXKQAK1VLW7Bgow8civn84mxzXXLDKCqeg8ZDIGM07NLQGD+pgg4AAzzs0mCQAAqigE7wGE9qIIO74ANTdIIzTEuUGEAIzzgA3G00xEn23qIAA2gaHDPAAauS-QAGIhAAJOMaq-roTAAYo+wGgAujumGjAAfLun6UNRA70b43Zgig5jwGwHHwNxvF-gJgHCWJYwSSM0njCylFyV6CkGrWYraWgfH-vponie+JkydMLLHEgmDQOpllbogrI8mAYTOoq3CbjR8DtN+05eGcO5KT28k+s+PSzkMmTziFoB8kG4bug6zatiwFgEKE6rwb4LpqvodRUOFthGPF3gtIxmAsexITkrM2TaJhLUvglYjNMlKlqRpPV9fMg2tWczS2RSM0DTl1oeEK3BpNS-VBtOACEeVlByFBDMwtgqtw5ikL+PqVvA8AhENRQje1zGsZpr2+EggSrIgERRDEcRzcNbVjV2iATSEU3wF9fi-SE-2RNE5xPjl82jUtcM-UEiMAyjwNrRjb2dR9PXgsCHEQiDL1g+NkCqdDmmUhCYLU+joMLUtLPAmzwKDW01r9CgkAsD6HLGrY6BYKAABMOD4EiMpgfo2iMRVyAqhkmSC7rgumGETDwqARF+u4yvbSSnCa9AYtfAriv2Ew9rYMoxSgKU5RSjIdscnguDWu6oDO10buSM8VDNFHeu6wbRvILLZt0EyMSZhwhhEOODArCVbZBmwgEcmqQYoI9dpSBnl1pMWJLNSmkrcComQrCQvmhLgj3kK4We9lEKDYAALM0RExzHpgAFTjyCGDYJgmSQJPuVQNAOrIEH5haOWIQcMaLAAF5r-YFCAQFNGJrIHsN8oGedpsuGKq0pgAJKYLAF3IBwzqVPgWor+Y50EGQhnIOx9FCZwnByAAtNIC+19xR0AKvfa0aQOQqlyFoKgzsbDlkuoQW+9sQKCybC2POHZuyfF7FZNK04xwTjwPfXoAwsqLgPB+L8nQ5CpSArudkB5jjHlPPfC8wYbx3maA+J8NC3xsMoqYAAApgCgkCRBsERrJFg+B0qjkylkWi04RLNDpF8d8q4LKcg4T+XSgluEgTAvACC0FYLwSQihNCewJI4RAgRKgxEyIUTMVFayHUuqaXso5PSQkXJGTcqZcyASuGKQhlDdSoSeIOSsc5QyoBjKxNklRKhdEbLOwMGEjJkSsk5I8pROJXlpg+T8kGQJJJgrWnyh7BBHtkBpF1MaHAojWztK9qADUHIipryzhQWKFj8EUAALKczEElCGFCuHwC0TOJhC5cpzgATsMWRgZnzNpgtYJZN4C9R2rNHKhyFktG5itNgAtTA7KYFLe0kybnHNGqc7q5yKYUCpvza5mwjmCFeuDZSDNJrM3+XzNGByQW3MWsUnmoJ-kC31mAYWos7qYPhKgxA2tR7WlNhAbUxdQBIEgRqUAv94BEEQDdZ2xBg5VGsHocBipz7YF-icHIthCBNw7MhbOmAs6tGJdaROoA2LsHoK6S0lK2qUBFtgR0dLzHyrzhymUjxyidgMNyy0lUkCNFnpAJIvgTSoEgJYPOkzTCUVKNYTU5Lek0vdKQCVxLTAAGY-TLw7HUFQoqkgOVrHUNA9AtVlQLkwcxjw0DsEUeWDVvgRW2DFROFYndFVRhjK7FQRggA"&gt;Help type the scheduler&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Share
&lt;/h2&gt;

&lt;p&gt;Be sure to submit your solution by using the &lt;strong&gt;Share&lt;/strong&gt; button in the TypeScript playground.&lt;/p&gt;

&lt;p&gt;Then go to Twitter, and create a tweet about the challenge, add the link to your code and mention the TypeScript page (@typescript) &lt;/p&gt;

&lt;h2&gt;
  
  
  Need Extra Help?
&lt;/h2&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Discord Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The comments on each Dev.to posts!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat Challenge 4

</title>
      <dc:creator>Gabrielle Crevecoeur</dc:creator>
      <pubDate>Thu, 29 Oct 2020 20:27:38 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-challenge-4-4dal</link>
      <guid>https://forem.com/typescript/type-treat-challenge-4-4dal</guid>
      <description>&lt;h1&gt;
  
  
  Type | Treat Challenge 4
&lt;/h1&gt;

&lt;p&gt;Welcome to the fourth Type | Treat challenge! Today we will be stopping hauntings and putting puppies in their place. &lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;We were looking for some pretty simple types in this challenge:&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;Treat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;treat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;treat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;candy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;baked&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;type&lt;/span&gt; &lt;span class="nx"&gt;Trick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;trick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NoShow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
 &lt;span class="na"&gt;result&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-show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can safely and efficiently reuse the properties in each field by &lt;code&gt;extend&lt;/code&gt;ing them with an interface.&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;House&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;treat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-show&lt;/span&gt;&lt;span class="dl"&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;Treat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;treat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;candy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;baked&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;Trick&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;trick&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NoShow&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;trick&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can specialize each &lt;code&gt;result&lt;/code&gt; property with the specific value a &lt;code&gt;Trick&lt;/code&gt;, &lt;code&gt;Treat&lt;/code&gt;, or &lt;code&gt;NoShow&lt;/code&gt; will hold by re-declaring it.&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;Treat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;treat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;treat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;candy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;baked&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;Trick&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;trick&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NoShow&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;House&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;result&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-show&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;Which would give the exact string value for &lt;code&gt;result&lt;/code&gt; in each type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHIDcCmoBGjEDtQGt0AcBLDAc1AENQATAsgJwE9RIAzUemW0AF1oIGNsTTj0RkuAKBChaiAM7QANl1mhmkTu2idZIxFwA03ABaJGxTIlpkFCxs2sLQRLpFCSwXIzOR8xiYuoEcgBc3DJisoY8-NgqZBiUoBiQALSyRpAA7rIAdOLuoADC8WwwoAC2ZLjG3tz0eHKgmUb8RqC+WJRyfLxoTMwFnnLIMvJKsgD8+eJc9cgAEjCyyAC8oADe4qCgCpC+XASQGKE6vCRb0nKKXKEARCJit6AAPqD3vAJPr7fJaRmZt3EAF98s5LPY+MgACrhLigRAADy4mEoKkW0GWG0uYxubweXFuUVhoXW7XilHoJ2iJEMKCqiEoEypZ1IQNAILBtAh0I+gkRyISaKWyFJo2ud2inyJMWZRFZ4k53NAADlIABlf7wpEooUYkXY8VvX7pLJPEHiPhHHRhUTKUIw20AbQAuqA1o6LqTdvtDsc3ujMQBGQkGpQS2Eh-EkskJSlvAAyvtAACE6Gb2fpPTs9mJfXcA8gAMwhsVhvERom26MdCl3ACydBUqdo6aBme2XpzByO+eFoAALCWrmX3rbI8SsXTcJQ7oVIJBsEFZCGa3HbgAldDLWDL9ns8TO-KWjDWyWxe28l1u0AejvZn09-19gBMQ5x4Zi45lbwbxH4ZvbLFvVzR9bgLUAAHY30Nd5P2lAQ7jVLQ8F4ZZKDNA8jytOFkg1LJZFCVU8MyK93SzYDuz9MC+wANmgkdjX+DDDwKVVMmMMRSmgUAjDIJBjGQWYGkiGMuIqekBPKApkjhShoDwBR+D8UBYAo31YHIBIVNLLgNJQRgMTlNwpAoaAMCTNROFgHSNPJcgkkQdjOWWPhKLqBopiAA"&gt;Our answer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;This one either stumped people for ten minutes or was considered a breeze. We had a few different answers in the TypeScript team, but we think this one is the most elegant.&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;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;done&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="na"&gt;who&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="na"&gt;loot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TrunkOrTreatResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;trunkOrTreatSpots&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="nx"&gt;Result&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;This challenge was a great reminder that &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeystype"&gt;a &lt;code&gt;Record&lt;/code&gt;&lt;/a&gt; is simply a type-alias to a conditional 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;type&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;K&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which can convert the original answer:&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;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;done&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="na"&gt;who&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="na"&gt;loot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ResultMapper&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="k"&gt;readonly&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;&amp;gt;&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="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;P&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="nx"&gt;Result&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;TrunkOrTreatResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ResultMapper&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;trunkOrTreatSpots&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;into code which is both easier to read, and requires knowing less language concepts. Kudos to the folks who made it seem very easy! &lt;/p&gt;

&lt;p&gt;Here's &lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEBEEMDsHMBpQGEDyA1AkuAjATlABaQDOoATgKaQA21AnqAA4CuALqJKAEYCW0AJqAD20UKwIVQ0SK2aVhAMzFkeAYwDWwssqqs+sAHQAoEKACaQud2pCNhEsMasAtBUGshoPsVZVB-T05WMmZoTSFtYN0vaB8-YxMwDFFOEOICMU9GSkZIeQUIsQlQCgA3CmhWRDpLezJ+VSF+NyKKRPIKYmZqVlI+D1bQAHIAFRCwlDIx3QAlTu7eobE6RkkAdwI1DJ5SGkpIfjp2y3YhJX4ZSWcvViHSAFsd4n0OUAUKNaYyIVWyPU6AITtJAwUA1ZgdNYqXzDMahdSTaYyOZdHrEJYOUFCLgAKwoqnYrBWknEMnaPkgdD6omIdGgqlAax44kGPhUcGpw2C8MR+1YAGVGEJFgB+IxGRqxQnjBFTPmC4WkAC8oAA2kZQLDigAFPLqIaIDXDAASlmIkgAxNgDaAjUNTcxzaALQAmA12pARaAUbT8gg-d2aoba6iQVSSM6gADqEXSPEY7oAuhxSJKfOKiatQCiFqAVQBvI2agLegBc3CEQmoVGg8CLjP95bZ+jrms1NmF5bmjXqAB5m3BEDA6AA+IwAXwzxNAcImctm8zReez+Ii-F7mYoke5c6RAqFvVV0GY9y4PsTiBzPTHRgUoQJPBEoHukHUFBGKHAKAAFMQD8Ry03bcZV5XQFV6ABKctZ1lPcr16UBCzbDpZDIGl-wMSh+GYcNv2-bIykQVQ5EoSoILzEdEPrZDKFQ0QkOQxjNQMFiCNKVsmMY1ViLIUjWETcsGM4ziSwocsFBoc0OOEpiO1YQTx2kmTkI2IRywAInU6jOMnYTdLbRTEPHFMZxA+dkUXSCJ3FUwLAhVRQTYngPkGShUQQ0oeE4dSZlCdSOC4IRynFNNCSaTwVRfN8Py-b8d1g+V-wgiURGIKsKAMGxYDi8LkvaGMyHUYgjA8AJVXUkYdT1dTEwMUTl25Np2j9SxqEEAr1BK8Lys9NCfVAFrGBqzLK3YAtJ3aAAxSAeGoYrSqEcqHSdC0AGZhvqlUJLmprmqFWafWcHYMh+PQRBoMR412eROHeT5qD4TpuAoGxPnEHZbXFL7vpssAozyaB9HLBUDrIYrftAbADBnTY+l2Z9IEYVZ3GJUhsmxat7h+9oXWhyqfUkD7OFCsgZsqYRRHESQXyRlpNw4MhYBPCpWGx0xVuhuzQAc0RKGcR1JE4XI-kUQZfFUAhAYAR2YSQFG+e5BjPWA+G9bQJZoas4EkbBMlAWAKEJYoKAADzDdg3ypN4FfaNsqYZ0m6HLAhWFYRgAJAZpSgMDxgE3YhVBUJw-eJZwohkZwNdoCoDecF1nFW6BsAANiAA"&gt;our answer&lt;/a&gt;. Bonus: &lt;a href="https://www.typescriptlang.org/play?#code/PTAEBEEMDsHMBpQGEDyA1AkuAjATlABaQDOoATgKaQA21AnqAA4CuALqJKAEYCW0AJqAD20UKwIVQ0SK2aVhAMzFkeAYwDWwssqqs+sAHQAoEKACaQud2pCNhEsMasAtBUGshoPsVZVB-T05WMmZoTSFtYN0vaB8-YxMwDFFxSRDiAjFPRkpGSHkFCLEJUAoANwpoVkQ6S3syflUhfjditIpiZmpWYkSYjw4xOkZJAHcCNUyeUhpKSH4GS3YhJX4ZCkRVGFBa5nIKRmpIVUlUvtZhyQAVELCUMhvdACUOrp7QUZ5xYWhJAFtIIwRoJKnpKPRQAoyEI-m1zpdFKAAAbBULqe6PGQAZUYQh6SIA-EYjE1YuxUXcHnNWDi8aQALygADaRlAoAA5FcSgAFfLqdmIVkcgASlmIkgAxNgBaAhezRcxxaAJQAmAVypARX7aLEEISMdVs9nco4nREAdQiGR4BvgRgAuhxSKSfMSLiNQDc0RjqS9Ot0GaAAN5CtlMgDSMVAAFEAB7BY6sAA8AAp3RQVspvVTdLSegBKJnqCi1JTpzMU9E57G4nr2xA+FRwAB89oAXMHQ2zuwFfh2uEIhNQqNA7d3xx89R3G-oxxO2TY8R2Xk0GkmZ3BEDA6M2uwBfIx7gDcxIUoVUehEoABxauKHAKBTxFrxA75bLtyrmJpL-zHa9lLfn6bykCG46ULIZCiM+dIGJQ-DMCcKYpjk5SbHIlBVPmoD0s2nbzmyEFyKIYEEeOBgUahZRzmRYaqBhoLtvhtHzr2FAdgoNDijRLHdourAdkGe48bxk5CB2ABEEldmRB6yfuiBCU6nqfj6zyvAG+aHsSpgWHsWyiFRPAUKMbT7P67xlDwnASU8oQSRwA4VMSLrks0niMjeFB3g+aaqdWP50lpLpDhQBg2LAabuVpfSWmQ6i9B4ARMhJXKSLy8USfaBhsThWYUDpYC6pY1CCHF6hGElQgpZqUEUDqeqMFl4WDuwjJCYVoAAGKQDw1CJe5KUKkqEoAMzNbljKcf1BWdbSfX1c40yZPql7SNQYg2jM8icAoJmgNQfAdNwFA2KZ4jTLKxLXTdnXmvk0D6B283DmQvSddgBiehMpCXZwAJAq06akDkQhcMOfy3X0KpfWl8h-aArlkL1VQ-GZAPAkMHr5LAzB-KCUOmKNX16VIFCtNsfAtLGrSLuozCMFkpTxsjF5mRQsaJqAG6wEAA"&gt;the weirdest answer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;Don't freak out... Ok freak out a little bit cause WE ARE BEING HAUNTED! And &lt;strong&gt;they are after our code&lt;/strong&gt;! We have tried everything but we cant seem to get it right!&lt;/p&gt;

&lt;p&gt;Somehow they keep manipulating the objects set this &lt;a href="https://www.typescriptlang.org/play?#code/PTAEDkHsFpIOwKagNZ0gdwM6nQCwIYAuoAltgOaQlzmjwA0oARgK7ECekLohu1yoTiwBOOSMOQAHADb4AxkgBQIUtgIs4hBABNm7UPlCTI0rcPIIyhAHSgAksWTVthzCznJM15WB+gAmlyikEwAVghyhNjICAiSoBaEhNS0cgQ0OswIfHC6vEiYCoiY9H6YhJDxvGSgAGbCkAC2oASSkghwKXqgjfhONIJBdGERUaDCCPja8NLsfhWg5ZU8fNiYxpDI+kzZ+ABuJOLeioTs7aAASqPi+gC8oADeiqDjkE2YAFyXb40A2gC6z1AaDICE+Bjg7ABigAvooTmckBcfqB7k8XnB8I0EF9ysIUkDpuJwXAWI0dsIgehnBgSWSKUDyLhIOUAPxffCQ2Hwvy4JKSD4gdDC6waBAADxk+GoOnKLFqtWsciawAA4szyphoJztNAAArpCqNTDAABiWK4WoAEvgNFpdVbLWDtbl9bIFFqAKKSdDiXjQCaRG7WPmNaSKZVwcqgOK+4S8K5B4R3R5AlR8wiST4gWN+5nSbSBirJ6zicii5DAXPx3CwAsB67JuvaYAHTAkQitkjxlj4aTQCoiYBAhrvL6-IEvB7ArE40AAIk9mmEnIUoBt0mk88YROE4IArIxqblaV8AEygGGlF5TmfYr7zgAquCQAGkO2kOtvQLvwWejzSWBfAAzJe143tOmL3guer4MI0hBN+v7ngBJ5AaAoFXpOjx3nOT4vhAIiYAgyZIW8e4oTggHgph4G3lBeHPkgACCSQkHIZHEpRx7TOhACMYHYZBs4PkxoAAMqECw2jsJxFGgP+VFoX+gk3jhDEPgAsvg5QkaAABCOijo0cngnxqG8eCAAsqkQbhD6GYWKJnqZ3HUSBl5AoCcLwioz41Mq2gFMyLAFqAci2sR4VNJIJDSHpJENHuii1BokSHHALS2poAAURY3F8ibFuwACUqYvJG0bGai4yNuw1jGZgvzabw1i1Ah4g5S1uANTqTQ5WVABUtVJvVjXWPFNC8CV-wANwjj81hMiyxBovZC4APJhQAUggCoTLJnlwkAA"&gt;snippet of code&lt;/a&gt;. Take a look and see if you can force the ghosts to stop moving things around.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;You've been roped into helping out the halloween puppy parade, it was such a distracting even that you did the minimum possible to spend as much time watching the show.&lt;/p&gt;

&lt;p&gt;Now it's over, you figure it's time to clean up your code and try get &lt;a href="https://www.typescriptlang.org/play?ts=4.1.0-beta#code/PTAEE0HsFdQc0gF1AJ0gBwKYBNQEsA7RSURAC01AGNpFMBnZMgQwBtXIB3TTA6yALZZEeEZAIAaUACto2OITgAoEKGyQ4cAJ6gW7Ljz7D+jaAIahmycpWYEC0NqHTMUzbJgB0oJUo9VWV0oAM2gCKjE+fzwPAHVCAkwUAAoAIxQebAAuUEYURSkqSFNzHLzFAEocgG9QAmZS3MR8gjgpADcYzEgy5sVQAF8lTkJ1Tk9ouISk0ABeXMFuxIBRVnpMABFMKi76X1UAeTIpZgjHdh0tGDUYggByZABaBfNxSkw1ygRrEnVSClAoT4qVEnjBKjAABUyDA4GRQFdYFQ7KBOFYqPDRKBxKAAF6QQQ5MiIRDoLIgTiUzzEIQAa0I9HoAEdHBl1HAUGFPEUBMA9BxuLx9mAAJIERiYdxSRF3dqUVKGSz0Wk4UgkCisdCkNisHTQLXMXJFDKpSCuXCQYL-SgCYrICHODDQQIoEyIMwWU7G7D9YjW0C2xiO9DO1ygdKZejeKDQWXy6B4ViIB0wZCGll4Ki0-BCViYcxEKx4HEKgVSVK0fDIDjreikLRYfAEYKQFACIviTzC0AAOS4-qKRAYyDwdcgcpQ0uuwR4rCrdzriNd2FoOj9GWCp2IrvIo4dRQ8atQmEQzEI9cbhBbbY7fGeMrluklKFw5Cs-oALJ4AIzhk+GwgAjkBgHXoRZd1aVEyEzeENXQOsRnIC9+nKSD2wIPAQ0CSIuyUQcgwjHA63mABtAAiAAJGACGwMjQCkMiAGFWwUOiGIABUWNwMLsMiAF0lX4cVk3w5AihKCxSLI9izHQekCDY0BKKQUANg0RSyIAITMVI81ATSeH4wTRN8IEImLPhTwuTisNceJ7CSehkgAfUI7B6ByRAG26K03PoKRnPE91zA8i8fLdD16AqUBqiUUAhKDEYHJQUKACVtlbbAAB5ULaSwCC0AA+OYYqGOLAVbUBklE8MMlVS1QFcur3Oi2L4vi68qpqoKPWxK1ArtSLWvK9qEpHXB5gAAwAEmqNyBkeWaevMAZJupSAABkDBQRjmHWZIKhG9qksSFKSJiAT5kmTB7NOtJmsKQbzEO0ahnisr4oyd0UD4E7HKUMrVBjagUU5SzoLrTAAA8GnQPTz0ymY-XWShOBYawAXoFhGwamw1CsQ0OEgWk61YPAVXLWgHTxjJ6GdZARnYXRmEfFUtAQ6CMUsDJQAFJJkXWXBOswCcdAEPAob62rMny3BlswKQvDgLJu1i1RRrImEwmwR4QzpQgyJqMFPAGCQHQ1rWaMeGFkHZQ2YuN03zfazXqJ1isBF0+VDKNsEnfVl3jQUXXZPk+3qkd534uNh0ypqv6UpKqzdRs0MUFuxz7sjR6JKivDxDAvNPA4OBkgTvOHXYvba2GaYztd7WQ-1hS+M8epzG7ABlLXWCFs9WFr5L6HIvW5MIJux5bzxOg8SAu-QSBEySPBgkzUhMLrUsuBV3xd733fVG-HJoVHcME17sdgitLo9sBNABHxnQAGYpDRmCz8TdypfQDJOhgOtsDMHZmqOe+9VAACZj4AjwLmfMvBTyRFRImOcGQMw8xRJNPak1sQ7k4CQNge1KYM1EPCMCHcA6olbNmREIMjCuBEDqHQq8aL5XyvQbgKB9571UAAWTPAQXUMhoBBncD6SC6YExZhzHDOBhZIhSDAv8d8NDkR8DBv6fckBDzMFNI+RCWs0zODQF7AQO8zKILIUsTAqx1hbB2B4JyTVMi9BaHlAaEkXGVBqHUBomBPGtA6F0HoTRXGDDau1IGDAThMxsOsNQGg6wsEfIaduqNOaYjrLIERT4oYHi8GCZmZAjo1TgLwVKdgKLQxKskegeBcR+LqDpJI0VZjFRIsbAAgigNwWgal1MwBUVu7Z0DJAOnMYqfDyCeGCETFIkyyCeG4uoAQYyABUoBvwADYKjrU7n0VoyQtkVB2dIReBBkh3DuBUAA3EdL60AfoxSOqNVJORSkEHKQQSpUNkjbLNqNUaM9uhvLKRU6GvyXrtSGAMIAA"&gt;it type-safe&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submissions
&lt;/h2&gt;

&lt;p&gt;Be sure to submit your solution by using the &lt;strong&gt;Share&lt;/strong&gt; button in the TypeScript playground.&lt;/p&gt;

&lt;p&gt;Then go to Twitter, and create a tweet about the challenge, add the link to your code and mention the TypeScript page (@typescript) &lt;/p&gt;

&lt;h2&gt;
  
  
  Need Extra Help?
&lt;/h2&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Discord Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The comments on each Dev.to posts!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat Challenge 3

</title>
      <dc:creator>Gabrielle Crevecoeur</dc:creator>
      <pubDate>Wed, 28 Oct 2020 20:00:36 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-challenge-3-446j</link>
      <guid>https://forem.com/typescript/type-treat-challenge-3-446j</guid>
      <description>&lt;p&gt;Welcome to the third &lt;code&gt;Type | Treat&lt;/code&gt; challenge! Today we will be going over yesterday's answers and diving into some new problems to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;typeof&lt;/code&gt; operator is one of those small tools which helps you avoid duplication, if you already have the type in the runtime - why not re-use it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- type Pumpkin = any
&lt;/span&gt;&lt;span class="gi"&gt;+ type Pumpkin = typeof pumpkin
&lt;/span&gt;
- type PumpkinFromFunction = any
&lt;span class="gi"&gt;+ type PumpkinFromFunction = ReturnType&amp;lt;typeof Pumpkin&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;This one is a tricky one. Made a bit harder by an accident of not including every ghost in the &lt;code&gt;Ghosts&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;The challenge aimed give a subtle nod to day 1's question, where the rest of the challenge becomes easier if you first make a set of types via conditionals or Extract.&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;Gods&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;Ghosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;god&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;Demons&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;Ghosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;demon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;EctoPlasmics&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;Ghosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ectoplasmic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="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;This does actually work in the current challenge, even though it's not quite right. From there, you can create &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards"&gt;user-defined type guards&lt;/a&gt; to change the code flow in the main algorithm to work as expected.&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;areGods&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Gods&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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;god&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;areDemons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Demons&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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;demon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;areEctoPlasmic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;EctoPlasmics&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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ectoplasmic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;That said, let's try work within the constraint of &lt;em&gt;'maybe the TypeScript team know what they are doing, and this challenge is meant to be this way?!'&lt;/em&gt; - which is kinda provably &lt;code&gt;false&lt;/code&gt; from this challenge.&lt;/p&gt;

&lt;p&gt;In the TypeScript structural type system, you don't really need to know much more than is required, and you could safely create a singular &lt;code&gt;type&lt;/code&gt; for &lt;code&gt;God&lt;/code&gt;, &lt;code&gt;Demon&lt;/code&gt; and &lt;code&gt;EctoPlasmics&lt;/code&gt;, then declare an array of those 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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;God&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&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;god&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Demon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&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;demon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendBackToHell&lt;/span&gt;&lt;span class="p"&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;type&lt;/span&gt; &lt;span class="nx"&gt;EctoPlasmic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&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;ectoplasmic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;areGods&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;God&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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;god&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;areEctoPlasmic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;EctoPlasmic&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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ectoplasmic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;areDemons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Demon&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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;demon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;That type-safety is enough for the algorithm, but could bite you later on because &lt;code&gt;Ghosts &amp;amp; [x]&lt;/code&gt; makes any other property optional. &lt;br&gt;
If you are going for minimalism, here's a terse answer in 3 one-liners which takes into account usage inside the algorithm:&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;areDemons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&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;Ghosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;demon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;demon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;areEctoPlasmic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt; &lt;span class="k"&gt;is&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;Ghosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ectoplasmic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="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;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ectoplasmic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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;areGods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ghosts&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ghosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ghost&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;god&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ghost&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://twitter.com/igorbek/status/1321514610717904896"&gt;@igorbek managed to get it to two lines!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;You've been keeping tally of how the houses on your street respond to trick-or-treaters. Can you reduce duplication from the types needed to describe the results?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHIDcCmoBGjEDtQGt0AcBLDAc1AENQATAsgJwE9RIAzUemW0AF1oIGNsTTj0RkuAKBChaiAM7QANl1mhmkTu2idZIxFwA03ABaJGxTIlpkFCxs2sLQRLpFCSwXIzOR8xiYuoEcgBc3DJisoY8-NgqZBiUoBiQALSyRpAA7rIAdOLuoADC8WwwoAC2ZLjG3tz0eHKgmUb8RqC+WJRyfLxoTMwFnnLIMvJKsgD8+XyQGDphosqgALygANrioKAA3qAKkL5cBLOhAEQAEjCyyACMp4ajilxnImL3C2Khux2U9GcAMscsAAhOinUAAX0h+k2Oz2BzEQLOl2g11AAGZ3o8lC9wlx3q9nnCfn9QKcALJ0FSg2jgqEQmFbXb7Q5IskotEAFixcieuMWBLxX1QVUQlDOhUgkGwQVk7xJZwASuhrrA5ZDIeIALrTWbzaICFSrDZM+Gsk7sq7IABMPLGRNOBuwgpiZ0pxH4dMZcJZiItFytoAA7Ha+WSnS6BGcAMpaPC8a6UOna3VzLhJSDRjLZFbrWHMhFHf0c5AANlDOLJyTS2eTOoKADkssYxKVoKAjGQkMZkFx6nJDB02xVRT3ygVkunKNA8Ap+H5QLBfUWMLByAlF9iuGuUIxUURSAUKNAMEDVOpN7ylGv4okKBhEJknBguJZrnwV3UGlMgA"&gt;Help out here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;You have a list of trunk or treat spots, in your rush you hardcoded the result of your map function to convert it from an array to an object. &lt;br&gt;
Now the list is longer than three items, it's time to map that hardcoded result into a type. Can you refactor this TODO list function?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEBEEMDsHMBpQGEDyA1AkuAjATlABaQDOoATgKaQA21AnqAA4CuALqJKAEYCW0AJqAD20UKwIVQ0SK2aVhAMzFkeAYwDWwssqqs+sAHQAoEKACaQud2pCNhEsMasAtBUGshoPsVZVB-T05WMmZoTSFtYN0vaB8-YxMwDFFOEOICMU9GSkZIeQUIsQlQCgA3CmhWRDpLezJ+VSF+NyKKRPIKYmZqVlI+D1bQAHIAFRCwlDIx3QAlTu7eobE6RkkAdwI1DJ5SGkpIfjp2y3YhJX4ZSWcvViHSAFsd4n0OUAUKNaYyIVWyPU6AITtJAwUA1ZgdNYqXzDMahdSTaYyOZdHrEJYOUFCLgAKwoqnYrBWknEMnaPkgdD6omIdGgqlAax44kGPhUcGpw2C8MR+1YAGVGEJFgB+IxGRqxQnjBFTPmC4WkAC8oAA2kZQLDigAFPLqIaIDXDAASlmIkgAxNgDaAjUNTcxzaALQAmA12pARaAUbT8gg-d2aoba6iQVSSM6gADqEXSPEY7oAuhxSJKfOKjETVqA4RM5bN5mjQCqAN5GzUAIhGOr1FYAXKAy5rm82At6G1whEJqFRoPByy3Gf6G2z9P3B82bMKG3NGvUADyjuCIGB0AB8A4AvuPmxWHU6rRXQA2mxPQG2KB2uz2YDuJxshCPgmOBy2p6wZ-iIvxF8-lxxoHXLc71APczUtF160bV9WxES9uGvXsQJbB8n3ZBAYM1d9PznH8lwQACgJbTcjBIowFFCAkeBEUB7kgdQKBGFBwBQAAKYghV6BsswoSNuTzJEBU44gAEoG1zWVBJRBZSFPTVKFkMgaWEgxKH4Zhw1Y1jsjKRBVDkShKhE4s12gs8OkU0Q5PM0ADDsnTSmQs9VX0shDNYRMT0wmyLwbBQaHNJybNAbDG23bzzNQ0CKwi5sSPM+K4sQEtNxTHMZV5AtUV6ETSPFUwLAhVRQQcngPkGShstIUoeE4CsZlCI9IE7cpxTTQkmk8FU6IYpiWNY-jJPlYTcrTbsKAMGxYAGzrcvaGMyHUYhM061UqxrRaK0TAwL2LZRmDado-UsahBAW9QVoCNbPSUn1QGOxgtsmrt2FLMjTAAMUgHhqGWjwrrAx1LQAZie3aVX837DqOoUfp9ZwdgyH49BEGgxHjXZ5E4d5PmoPhOm4CgbE+cQdltDMKYp0wozyaB9AbBU4bIZb8rAbADBzTY+l2WjIEYVZ3GJUhsmxHt7kp9oXQ56sfUkMnOHashvsqYRRHESQ6P5loeI4MhYGYe4KlYCXTGBjnCtAYrREoZwgdeXI-kUQZfFUAg6YARwOt5vnuQYuAoWA+G9bRXZoHs4EkbBMlAWAKEJYoKAADzDdgGKpb2hHF0xm3V3WlboBsCFYVhGGIOsQGaUoDA8YAeOIVQVCcWviWcKIZGcUPaAqWPnBdZxgegbAADYgA"&gt;Refactor&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Share
&lt;/h2&gt;

&lt;p&gt;Be sure to submit your solution by using the &lt;strong&gt;Share&lt;/strong&gt; button in the TypeScript playground.&lt;/p&gt;

&lt;p&gt;Then go to Twitter, and create a tweet about the challenge, add the link to your code and mention the TypeScript page (@typescript) &lt;/p&gt;

&lt;h2&gt;
  
  
  Need Extra Help?
&lt;/h2&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Discord Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The comments on each Dev.to posts!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat Challenge 2</title>
      <dc:creator>Gabrielle Crevecoeur</dc:creator>
      <pubDate>Tue, 27 Oct 2020 22:56:59 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-challenge-2-3n16</link>
      <guid>https://forem.com/typescript/type-treat-challenge-2-3n16</guid>
      <description>&lt;p&gt;Welcome to the second Type | Treat challenge! Today we will be deriving the types of pumpkins and busting ghosts!&lt;/p&gt;

&lt;h2&gt;
  
  
  Yesterday's Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;The solution for this challenge used &lt;a href="https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html"&gt;indexed types&lt;/a&gt; to extract a part of an existing type to avoid duplication. The need to use &lt;code&gt;[number]&lt;/code&gt; is an interesting twist, because &lt;code&gt;[0]&lt;/code&gt; or &lt;code&gt;[1]&lt;/code&gt; (or any number) would have worked just as well too. Doing this right would also have raised the typo in the original code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt; Your goal: remove this any, without changing GhostAPIResponse
&lt;span class="gd"&gt;- const displayHauntings = (haunting: any) =&amp;gt; {
&lt;/span&gt;&lt;span class="gi"&gt;+ const displayHauntings = (haunting: GhostAPIResponse["hauntings"][number]) =&amp;gt; {
&lt;/span&gt;  console.log(` - Title: ${haunting.title}`)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHICcCmoC2BDA1gSwHYHNQ0dCAHE0AdwAssBjK0WyHHRWgFwGdR3JDQAJmnZoARmk6IAUCFCQAZqAA2kWmiWg8VSJy6EcAnlURZ4oeWgBuMeFnbIqaaDi4A6KTLBRohJIyTCuATsxoxKWIgulDT0jMysHNy8RsKCwmISiAA0nvqGAJ4woI6WyESgAIIACgCSoEicJMySmpGI8MKIhvKQZoU+Trzo7HTqSvnuuQDqxsT9oLpo8Ow88PlBPHwCWI1KaPlGDk4uQZxZoPMB4QBe0rIhqfMCzLArGDiQFMWfmzz5JMgQsgSEs0ChEPYzERDAAraC6UDw5AAAyI+WRk1kqJw6OKElAdm4JD2tGyoFE0BWaDiSiUiDQeGgyCQTBQ4IMXRSK3mahwuSRoFgNQ5AA9OQAVf6ITiwX5IFCQUqHQVo2UUOzaSmMRz4DZA3IAcW0umqNQAStKmjgWuwpZNbQDQEadOxTRbGs1kABeUAAbykoFAODBiAAXAt2LZ8AHyaYQgARToAfnDuijeBjAnpCeTqcjQRjoiwkDz6Y8gcczhG+E44Yq8A6+QAPL6eHY6aWgucSPBFZEiKTO-hzio1CNmEOCABfAB8UinHiY1pW212+2dCJ9AAotC7wxvXbV3VbJABKUBemd+mNLziQOmuFR4LfIgByIfDABJfbvdK5g+CU7IqeMZYIoO7GuwrhFssVCJvY563veiCPpAz7IgAQnGVBCPkX4-pB0HYfBiBASBgZgaAEEuq4WbCHBnSIc0yGoeh8YRAI+G-lBdE5vYZE3sxD5Pi+AA6OBYSWoDftxRGQAJgnWixInIuJ9bsBQvQYLWwExrJlYnDWrg9PAACiaD0FuSwaVpF5Xv6gaBquxL7AAEsc1Z4JwVnLJp8AYORoBTiBC65N4Zh4JA6jhvKfZGDs+j5Oc6ohDAKz0EQeAbAebqWp6Ui3iuOwufk7lVqcF5UQZnn7pBuUetaiAANoAETVacLUALpNTg0AoKI7Sdeel7XoGSHCWhL6gAAtKA4rtmG0m+u1+CuCM7B0gJY1CShKmOd+K14KhY7FjgW1xEpE3ofty0eUErg9n26A4KSAmhUAA"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt; You're first going to need to separate out the candy from the treats,
&lt;span class="err"&gt;//&lt;/span&gt; you can do that via conditional types.

- // type AllCandies = ...
&lt;span class="gi"&gt;+ type IsCandy&amp;lt;A&amp;gt; = A extends { candy: true } ? A : never;
+ type AllCandies = IsCandy&amp;lt;ResultsFromHalloween&amp;gt;
&lt;/span&gt;
- // type AllTricks = ...
&lt;span class="gi"&gt;+ type IsTrick&amp;lt;A&amp;gt; = A extends { trick: true } ? A : never;
+ type AllTricks = IsTrick&amp;lt;ResultsFromHalloween&amp;gt;
&lt;/span&gt;
// Almost there, but little 'Bobby Tables' cannot have peanuts. Can
&lt;span class="err"&gt;//&lt;/span&gt; you make a list of candies just for him?

- // type AllCandiesWithoutPeanuts = ...
&lt;span class="p"&gt;type HasPeanuts&amp;lt;A&amp;gt; = A extends { peanuts: true } ? A : never;
type AllCandiesWithoutPeanuts = HasPeanuts&amp;lt;AllCandies&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our original answer relied on using &lt;a href="https://www.typescriptlang.org/docs/handbook/2/conditional-types.html"&gt;Conditional Types&lt;/a&gt; to narrow the union, however we got a lot of responses using the &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion"&gt;&lt;code&gt;Exclude&lt;/code&gt;&lt;/a&gt; utility type to make it a single liner:&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;AllCandies&lt;/span&gt; &lt;span class="o"&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;ResultsFromHalloween&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;candy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is a great solution. &lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcCdQNYEsAmBnUALAhgNwKaiz4AucAdvilpALaEDuSJmo2oDmkANoQEbYA5gCgQoAGbRu3UJHFZs0yA3z5yobpEgkANG3LUAnjADkBUCWwI1FzIRJJ6FyKFFhaVwuxT40AY1gkAAcHSHU5NmlZeRZ8WgAuYWESQyDCAGVybD8EACFsWAwAXlAAb1dQUCz6eNAAInSuWBJQAGEuPx5sEkJ8wrrhSuxaGHISWoAWQdA-bANDWpJYaHxhAF8klLTQAHFoWgFpYrKKquH8WrqdrXxDXf3D7jQBys7NWEvBYjU60AAfepBOBBXjPaazeaLZarDbJVKEACCQRBvlAJXK02qF3qSJRYNecxQCws0PWm3hbS0yFR6NOWMurSpSF8LxmhOJSxW0zSc2gJDQUK5sK2GXISBy+EKfTRJ0x50umXF1kKoD6rIhRMFq0qPPIfIFJKF5O2ABUtCwgtg0D0ZRjKvT6mbtJhLdb8KzaEgxhzSZUlkqtWS4dsAApqPxIGS0uU1eph8gR7is-05QOwsRQaAzYjdLygNBewS8UBBSOECKKGSxIi+KT8vSEjhzFokFzQNCrMQsJAYVv5nDEWR82yML1i8iCDDDMKCUDGOCIVBoAB0rhFoAASrXuPyAGKwOgACUrylU6hKmWyeQKGABewOldvoFxoP+oEVEqlBTfjMg1KfToWlaNoAvGiZJBmpiDuISCFC0giQIWzhVKo1B9h2lqwLmQ4tnYbLzBIB60COJL4N0aA6G4c4wPhoAoC4LDdKAuBIOwnQGMwSBhIoFjwiuwaItIrSEsyxwAKIAB5+Nw0A+AAPFuaB1mg+5HieKhqHopQaj6KxrAAfMahAAJJoCagQ5HJCL6TKCKgPgEk9AYGDlCmCBaqAaygAA-M+oC1JQBCwAA3AJz7SOZSo0qApmRZZinKaptDHkoGnkIZEFgAi3AjNaI7EHofDDtwzAkMWJi5JAfB8HcJrYHwoImPh5DaAo5i6vqq7CeQVHzqAHjWGwGg9i0EQaqJoAAFbti04iQPAmCON5YXHmgYa8vyVk2SUdkOU56AnB1-IeV5vl2QF+BBaF67Zdw3UoKJADqzBcHy616vyMqre9+pWUJIm+PpQA"&gt;Full link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;Lets take a trip to the pumpkin patch and try to find the perfect one for our Jack O'Lantern. But in order to make sure we have located the right type of pumpkin, we need your help in identifying pumpkin types.&lt;/p&gt;

&lt;p&gt;We created some starter code you can find &lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFdQCwIYDcCmoGlQJwJ6gM4AOKAxgJYIA2oh0AtoQNZkB2ANOiwCag4ygB3BCwAuoEZFAksKBCLQYROYqABmWSHVBkRAOgBQ+kKAAqWBFx1lILKpTxFZzFgHMOfWCRiUeXFKtYFcWU0SCxtURQsVQQSFCMwVTDxODR8RGIOACNoMQ90GVAbe1AXSFYXcUlEVBSyfCKWNFoGZzYEgkl8rhsAcjFVFBRqSjJGNB1ehoEwkThQLmhCUZI5CpS0PwCWKxsDfS8WfDEWplZQAF5QAG99UClISjCALlAAIhxhp4F6uDf2+5KYivN5laBYLj-O4EMgALxQIIAsihLPQofcUE0sC4cCCAIwABgAnKAANIAKxoUVAhIJLnRam+URRrxilHwKABMPhAGFESCAKwE3QADlAAA9QAAWYUANgloAAzMKAExSOhQgC+AG5DMYAJJHeQWIqqKQyNaudDBFSjcbPBIdIFoAAK9DOLEuN1AHXuXieWFexywFV9oF0EY6msdxh5wl4-Hy0A5NpQkDNzoaEnNsnk1vwFUoaFGWIA-IZnaA3a1zldhDg9WAAHIocViJYcGQchBYEjzOCQAQJzzx5NBXJkUZKVNVeDCLhFp2pAgIOjNDRZItaH5za2qaAsEgiawsXSgAASg6k8fyrZE5iPGw6MhE4M9lfUmjqDX3h+PNlnFwUDEOY0lXNBnXLA4bGOHM5BQABRcVV2WFBqw9L0AAoAEpLgAPhuaEXzfGh3WcfRo30St0OcAAxDQ6Fog8jxPL1630IA"&gt;here&lt;/a&gt;, lets see if you can finish it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;Your job busting ghosts just got real tricky. Before you head in to &lt;em&gt;guard&lt;/em&gt; Manhattan, you need to assert to those ghosts who is boss. Help &lt;a href="https://www.typescriptlang.org/play?ssl=49&amp;amp;ssc=69&amp;amp;pln=49&amp;amp;pc=73#code/PTAEEkBcHIGdQEYFMkDtQEcCuBLSTQBDdJANzR1QHMAaUWAewFskHUCAbJSUBrHwhw4BYAFAhQkABYEqUhrEjwAnn2jlEKdAGNCkbVMpVQAMwYAnUKqyWTOc4qtJClyqDESEWWJSSxYAHSgACpSenCgqAw8ZGiSMqAA7haOCHjxfHJ0HmDpkDao8Hw8VAwAJvDEZaBlSExsleYEgoygTYLu4mBVRE2RDIlEQrzklgCyxGGQkMQBYjkhCQjmhJRFJlZ8lviETKBh8NrMBFgADkl4UkTogqXml0wLZpa1gkYX0vEEp+YMCFxMIKhJDKIj+JDmHjSHCVDh3B6dCQwr68VAcUGJQigtyJQwGTZYUC6dCvDgfK7SAgw2BYJBzUQLYGgsIaWDcUBnIigDgwngMDZNU4WfDVOQKJTAWr1QrAUoVBY9FnNWAAayQ1RwG2sROIphwwzcjBYvA2lJq3FWHFgCqhS2ikGYiH4-R4BmIVAIlPsRPKdPmXVAAGUZqC2ATLFQsC4yvSxJBlKcCAA1HClUAAXlAAG8xKBIrskAAuUAAIhTaaTYYAEswvOZjAARJD8WAGNBlCwmEs0XOICyoYslsYMDgd0iEEu9qRYJjEcCwKTFyDmWliAC+-vjidAAC0sFgyZmc6I86gC4O9wfu72pWwlyukL22agygAhQjaFXBBhVpBCAAUACUxakAwOBlOum4JsmlAAF4ZtmvZniwg4pqg8EAMIcMK8jXie5rSveq74c+b4fl+P5-hwQEgWBEGiBuDKiFuBAAOI4LBEIIcep7nqWaGYdhkK4T2+FykRj74YYABW5HBliAAKWAmCYEyoDRoCgeBkFMSxQY8iwliZoh+HIUWpaBgZEJ4XmRxCYOrFNGgAC0oJsp6Ui-Fgcg2aASDaA6pwcIQsBMDg2gSTpcbQaArHyIo8CZuWDCgAAPru+5kulAn+rU2jBX0JhYKgAU4GGC4MJ+ACCL7BCspz-mKCXFlV5grMoAA8WZ+QFDBBSFYURZID5rgAfMBml0f6wAAFQzaAAACtQ-P5ejqqAznxMiyIIIQ1R7aQ4UEDNwBiHlBUEEVJWQGVOi-P4wLBu0TCwBpWn0WIV2lWGlDkIoqZrQASkgQqQo18VKMWcXirAADaAC6gEmXmmqgP+LhIKx5SvU1SiAUjPF5qAEgAKqFDYVIbMiZr3HItrvA6NQML2eaeM66RHAe1TJOYKos0S92wI9y7OC9QH800+TmKgvaMb2Eh1eFKqgl4PBGtwhjUBAW2oCqSQEMSnSs2AYQvlwqJcrobLOQgyjOVbBC7T41r4aj6NNE20o4xDsD48jRPPGjRyFDwt7oPyoC477-tEwRbABKR76ft+v4AYB-OMXmcv4RIADqSDqAQHbsFtlTctE-SJKJxv0PIXOoNAPDIJIDApWUmp2NoB6QL2bsYwAor1CnBaF4XgzDfuE3mFXVbV9Xjwl6f4Yx2cSAA8gA0nQ0LwNTCTtiaPq1EkeJXMSjdEqbHpBAsGG6tqiT3PgpjFd9hSaNhgy4uFVyJPqZJcFtM0BADANALCOMfI4TBTj6iQAAfggDAeA2EGAqneCtaYbkIRlW8LwZ0lImg3yYhILG5RuRYE-EEeSoZ0DWAjFGcwMYgA"&gt;finalize the ghost-busting algorithm&lt;/a&gt; because who else are you gonna call?&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharing
&lt;/h2&gt;

&lt;p&gt;Be sure to submit your solution by using the &lt;strong&gt;Share&lt;/strong&gt; button in the TypeScript playground.&lt;/p&gt;

&lt;p&gt;Then go to Twitter, and create a tweet about the challenge, add the link to your code and mention the TypeScript page (@typescript) &lt;/p&gt;

&lt;h2&gt;
  
  
  Need Extra Help?
&lt;/h2&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Discord Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The comments on each Dev.to posts!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>challenge</category>
    </item>
    <item>
      <title>Type | Treat Challenge 1</title>
      <dc:creator>Gabrielle Crevecoeur</dc:creator>
      <pubDate>Mon, 26 Oct 2020 18:09:01 +0000</pubDate>
      <link>https://forem.com/typescript/type-treat-challenge-1-829</link>
      <guid>https://forem.com/typescript/type-treat-challenge-1-829</guid>
      <description>&lt;p&gt;Welcome to the first Type | Treat challenge! Today we will be extracting haunting data from ghosts and sorting Halloween candy!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beginner/Learner Challenge
&lt;/h3&gt;

&lt;p&gt;So the TypeScript team is being hired to investigate recent hauntings in the community, and we are trying to figure which ghost is the trouble-maker!&lt;/p&gt;

&lt;p&gt;We found an API that will allow us to get data on the ghosts however, out code isn't fully optimized. So we need your help.&lt;/p&gt;

&lt;p&gt;Head to &lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcHICcCmoC2BDA1gSwHYHNQ0dCAHE0AdwAssBjK0WyHHRWgFwGdR3JDQAJmnZoARmk6IAUCFCQAZqAA2kWmiWg8VSJy6EcAnlURZ4oeWgBuMeFnbIqaaDi4A6KTLBRohJIyTCuATsxoxKWIgulDT0jMysHNy8RsKCwmISiAA0nvqGAJ4woI6WyESgAIIACgCSoEicJMySmpGI8MKIhvKQZoU+Trzo7HTqSvnuuQDqxsT9oLpo8Ow88PlBPHwCWI1KaPlGDk4uQZxZoPMB4QBe0rIhqfMCzLArGDiQFMWfmzz5JMgQsgSEs0ChEPYzERDAAraC6UDw5AAAyI+WRk1kqJw6OKElAdm4JD2tGyoFE0BWaDiSiUiDQeGgyCQTBQ4IMXRSK3mahwuSRoFgNQ5AA9OQAVf6ITiwX5IFCQUqHQVo2UUOzaSmMRz4DZA3IAcW0umqNQAStKmjgWuwpZNbQDQEadOxTRbGs1kABeUAAbykoFAODBiAAXAt2LZ8AHyaYQgARToAfnDuijeBjAnpCeTqcjQRjoiwkDz6Y8gcczhG+E44Yq8A6+QAPL6eHY6aWgucSPBFZEiKTO-hzio1CNmEOCABfAB8UinHiY1pW212+2dCJ9AAotC7wxvXbV3VbJABKUBemd+mNLziQOmuFR4LfIgByIfDABJfbvdK5g+CU7IqeMZYIoO7GuwrhFssVCJvY563veiCPpAz7IgAQnGVBCPkX4-pB0HYfBiBASBgZgaAEEuq4WbCHBnSIc0yGoeh8YRAI+G-lBdE5vYZE3sxD5Pi+AA6OBYSWoDftxRGQAJgnWixInIuJ9bsBQvQYLWwExrJlYnDWrg9PAACiaD0FuSwaVpF5Xv6gaBquxL7AAEsc1Z4JwVnLJp8AYORoBTiBC65N4Zh4JA6jhvKfZGDs+j5Oc6ohDAKz0EQeAbAebqWp6Ui3iuOwufk7lVqcF5UQZnnhmi56XtegZIcJaEvqAAC0oDiu2YbSb61VBK4IzsHSAlNUJKEqY534DfgqFjsWOBjXESkteh039R5g09n26A4KSAmhUAA"&gt;this link&lt;/a&gt; and help us figure out the best type to use in one of our function parameters!&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate/Advanced Challenge
&lt;/h3&gt;

&lt;p&gt;Your kids have come back from trick or treating with a lot of loot. Someone's going to have to sort this pile, and it looks like that job has fallen to you. Can you conditionally filter the pile into manageable lists?&lt;/p&gt;

&lt;p&gt;Head over &lt;a href="https://www.typescriptlang.org/play?#code/PTAEE0HsFcCdQNYEsAmBnUALAhgNwKaiz4AucAdvilpALaEDuSJmo2oDmkANoQEbYA5gCgQoAGbRu3UJHFZs0yA3z5yobpEgkANG3LUAnjADkBUCWwI1FzIRJJ6FyKFFhaVwuxT40AY1gkAAcHSHU5NmlZeRZ8WgAuYWESQyDCAGVybD8EACFsWAwAXlAAb1dQUCz6eNAAInSuWBJQAGEuPx5sEkJ8wrrhSuxaGHISWoAWQdA-bANDWpJYaHxhAF8klLTQAHFoWgFpYrKKquH8WrqdrXxDXf3D7jQBys7NWEvBYjU60AAfepBOBBXjPaazeaLZarDbJVKEACCQRBvlAJXK02qF3qSJRYNecxQCws0PWm3hbS0yFR6NOWMurSpSF8LxmhOJSxW0zSc2gJDQUK5sK2GXISBy+EKfTRJ0x50umXF1kKoD6rIhRMFq0qPPIfIFJKF5O2ABUtCwgtg0D0ZRjKvT6mbtJhLdb8KzaEgxhzSZUlkqtWS4dsAApqPxIGS0uU1eph8gR7is-05QOwsRQaAzYjdLygNBewS8UBBSOECKKGSxIi+KT8vSEjhzFokFzQNCrMQsJAYVv5nDEWR82yML1i8iCDDDMKCUDGOCIVBoAB0rmDhAASrXuPyAGKwOgACUrylU6hKmWyeQKGABewOldvoFxoP+oEVEqlBTfjMg1KfToWlaNoAvGiZJBmpiDuISCFC0giQIWzhVKo1B9h2lqwLmQ4tnYbLzBIB60COJL4N0aA6G4c4wPhoAoC4LDdKAuBIOwnQGMwSBhIoFjwiuEFgCKz7SK0hLMscy6SVRQkItIJqBDkElSVRskjNaI7EHofDDtwzAkMWJi5JAfB8HcJrYHwoImPh5DaAo5i6vqq6ieQVHzqAHjWGwGg9i0EQauJoAAFbti04iQPAmCOAA-AJvHbLJ3AuSg4kAOrMFwfJhry-IypJy7CEAA"&gt;to start sorting&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Share Your Code
&lt;/h2&gt;

&lt;p&gt;Be sure to submit your solution by using the &lt;strong&gt;Share&lt;/strong&gt; button in the TypeScript playground to copy the link to your clipboard.&lt;/p&gt;

&lt;p&gt;Next go to Twitter, and create a tweet about the challenge, add the paste the link to your code and mention the TypeScript page (@typescript) !&lt;/p&gt;

&lt;h2&gt;
  
  
  Need Extra Help?
&lt;/h2&gt;

&lt;p&gt;If you need additional help you can utilize the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;The TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/invite/typescript"&gt;TypeScript Discord Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The comments on each Dev.to posts!&lt;/li&gt;
&lt;li&gt;Beginners may want to check out this &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types"&gt;page from the TypeScript Handbook&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Typing :)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>challenge</category>
    </item>
  </channel>
</rss>
