{"id":3156,"date":"2021-10-26T11:28:18","date_gmt":"2021-10-26T19:28:18","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=3156"},"modified":"2023-04-27T13:10:08","modified_gmt":"2023-04-27T21:10:08","slug":"type-treat-2021-day-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/type-treat-2021-day-2\/","title":{"rendered":"Type | Treat 2021 \u2013 Day 2"},"content":{"rendered":"<h2>Type | Treat Challenge 2<\/h2>\n<p>Welcome to the second <code>Type | Treat<\/code> 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&#8217;re on day two, which means going over the answers from yesterday and showcasing 2 new challenges.<\/p>\n<h2>Yesterday&#8217;s Solution<\/h2>\n<h3>Beginner\/Learner Challenge<\/h3>\n<p>The first part of the solution for this challenge used <code>as const<\/code> to trigger &#8220;Literal Inference&#8221; &#8211; basically telling TypeScript &#8220;Don&#8217;t convert the array to <code>string[]<\/code> but consider it a constant set of string literals. This meant that <code>playlist[0]<\/code> stopped returning <code>string<\/code> and started returning <code>\"The Legend of Sleepy Hollow by The Monotones.mp3\"<\/code>.<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre>  const playlist = [\r\n      \"The Legend of Sleepy Hollow by The Monotones.mp3\",\r\n      ...\r\n<span class=\"pl-md\"><span class=\"pl-md\">-<\/span> ]<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> ] as const<\/span><\/pre>\n<\/div>\n<p>The second part of the challenge used <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/typeof-types.html\" rel=\"nofollow\"><code>typeof<\/code> types<\/a> to extract the type from the <code>playlist<\/code> array. Without the first change, this would be <code>string<\/code> but after the change this meant the full array of different types. You then needed to use the <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/indexed-access-types.html\" rel=\"nofollow\">type index syntax<\/a> <code>[number]<\/code> to declare that you want any potential string from that array.<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span class=\"pl-md\"><span class=\"pl-md\">-<\/span> function playSong(song: string) {<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> function playSong(song: typeof playlist[number]) {<\/span>\r\n      api.play(song)\r\n  }<\/pre>\n<\/div>\n<p>Successfully completing this challenge would raise an error in the final code samples due to a subtle typo.<\/p>\n<p><a href=\"https:\/\/www.typescriptlang.org\/play?#code\/PTAEEkDtQBwJwKbwIYBcCWB7aAzTdQALZAGxMwHcEFIAaUAT0wFcByANwVACMEBjTAFsuqQlwDOxRABNQAEQBSoPHABQIUKRKMWBHHHQ1p4gHSgAmiw4SEqUMxihREhuNQJBTzKGno3B7mZ3JzFQQWZxdD51MAj0SABzEK5CdEdIBAonBhgEdBwGUABBAAVwMFBVVXRBGHw7AG9UHLyC0vAAX2U4IVAAImbcgFp8IdREND6qgUg3WBJkBhI-OwBeUABtVVAd-oAVUIAZBASjUEwcUABlEmoYQoAJTDJKHkKDrgBZbExUbARTLUAMx9WjbXZ9AAU4FQrHEmgAlKBvrN3HA4aAnstpIs3qAAELMPgAa1AAHkqLMTMDQeCdn18d5PtRUPDnMjsG4EARuIVGfJ0NJpLcGNSYCCwbt+iVmHAYLdQCUEJh5VwAKJobnIlls0IAdXQqD4hHkmD4fx571C+PQSUZMFycDFErp-SufAmgniBK0oEhaHkcGQfGYC0xWiRvNAH3kzBK2FZztpUoZaEEyDooD1zxw6czADEg5BiTQufF6PhA8HQ8g8TG5OhkIJsMYk5KIYWMyXUXloHsKCs66EAMJwVyoUiA8XJiGsA4GMjc1h4z5RYgIbQKYPE8TYJOqAC6mnhMzcVXli2WZ40AD0APwxaMtd0GGB2UTxHchPygH+1q92BcoD+PECTiPQFCpMav5snAzBcEMPBBKAfAZjozCVBo6Ylk+uQvmk74TO+oQXksg7IHAQaFM2iD9MgJ6chOkCsn0D6qKedjIDA6CgOsgytAw7SQn0ggMAA+lx6BiSWDB9AiqiSSYMwZOakLyaoODMJA5pYNApFXNgCSQruiQAFzZLkQGkQBGyQMwgi8HAB5Ig0rqKaRxmGfJHTngsDAGYkwkynKCpKiqCoami2q2LqXAGkaJpyGaFpDlwNp2iqjpJupGgHD+FD4F+CREQAhASyGGihLAkLIvCaKAyyoKgCo0VwiCRFyzFeBZmDgShaFMMwj4fsW5yXLWFC4n8KHEIkIihAABvphkLaAC0mQkq0wBRTa2FqiARPNXADC0Fx9MkmFgNZKz0LuIQBnsz4egRoBBn4AKaNA3I9AQ+TJIgGK1oMmBsctgVQjCgNIiiXLovCWKCriUaEiS5KUlOILyWDRl9DGxynJAshATcdyPM85BZFGMYor8-wY3JqjY8J+Jphm9DZiQuZs6AnbFqW7jlucBByBRIZhlToQNk2Lb0wiQA\" rel=\"nofollow\">Our answer<\/a>.<\/p>\n<h3>Intermediate\/Advanced Challenge<\/h3>\n<p>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 <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/utility-types.html#returntypetype\" rel=\"nofollow\"><code>ReturnType<\/code><\/a> with <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/typeof-types.html\" rel=\"nofollow\"><code>typeof myFunc<\/code><\/a> 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.<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre>  const findOldCostume = () =&gt; {\r\n      \/\/ ...\r\n      return { jumpSuit, estimate }\r\n  }\r\n  \r\n<span class=\"pl-md\"><span class=\"pl-md\">-<\/span> const createNewMask = (costume: any) =&gt; {<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> const createNewMask = (costume: ReturnType&lt;typeof findOldCostume&gt;) =&gt; {<\/span>\r\n      \/\/ ...\r\n      return { ...costume, mask }\r\n  }\r\n<\/pre>\n<\/div>\n<p>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.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-k\">type<\/span> <span class=\"pl-smi\">Costume<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-smi\">ReturnType<\/span><span class=\"pl-kos\">&lt;<\/span><span class=\"pl-k\">typeof<\/span> <span class=\"pl-s1\">assembleCostume<\/span><span class=\"pl-kos\">&gt;<\/span><\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.typescriptlang.org\/play?#code\/PTAEGEHsGcBcFcC2BTUAHATstpYEsUAaUAT0nlADM8BzeLUAIgHcALE0AO0llABMs0aKHg4ANngDWyAFAhcrVAENOsJTUic8cYXk4LUAZQCO8PH1ABxJSgD8jYnl7RkyRMMzJYsDsiXQSOTAAI39kC01ScgxQSDELcH8lflQABSU0ZDFY+FhqWAA6UCDQAApQVm80aAAuED54AGNJBuaNAsbIRGBbYwBeRqSAaj5kIbQMrIAyPCUADz6CdWRoGaVFxGXoAEoZEoBNclAXXn9zVHwUXEgqWnpUcl42JV4yeAByBg09GmuuVwssBuJU6nAAbsgMLxYIpQKC4EhlJwLNBpLBGqwctDYWgeMhVLNssxIBhJNcSjQ8BCovQXGJKKAVKBzslIAzLitBmJkDU9gRcVDQABvFxKDAY4iYPSwSEAXyoGC6TB8mQAtCTVbAsC9GHt4bxqMiAPLxKAIq59MrbUB9AB8wpkoCdcM0cFAACskGhDGZeJbReLWAUXvhGqVrQAfCPHPyBjpiGBecOgKMxsUYgo0MXLcOO5360ArS4vVCWgDMAAY806sAgMPohR6vT6nMQi0sZaBZTJuzIC41tTKAHLIZgAWX8ZMtpU65p5oAASl56JwACokTIAHhVyDZt2NppgCBQtutdodzpdnDdm1RNvQGGlkIKUtUE9Rucvt8kBWgrEm96MI0eDityuqXrOx7IAU7abJ2QyWgAbFWl61iuwqgAUWGQYixDfl2PZ6q6vADn4MoAEKQHwJCJCgGDJNOOEoDUTpLnWa4bsg26cXupEliO46TqeNr2kK1ZXm6gx0QxD5PhgL6PqotGQkon7OvIACSTx4GI2ScAC6BKNKPzXJA4lMdBsElqACGgAALAArOJaH1hhWEdEeuFwjYKkEb2Bb+C4iDBNyZpQfeybnmJqHLq5fEUVRNE+fRM6DsgAnvpIpSGnwJp8GFiLhtsuy9vIliDsQMLaHCaXCEygVuCFHASPpsQMkoukGIZUJ1ciJQwqgxKkjS-zhH8fCQEUAASkDMMgEIYI4vBYBIKyxPoAAGKgkBtwhsHgGLFPImzSHtJKSCZzBOJiA2Mo0CAdS6c6MqAwROIywV3OQtREdeJGeRajJCI1oUA8gubyM6AB6th7PIiT6G8Ch6GSe7JMwSgcECtxzF1eiUJC+KNIN12PDVZE-CU+nMKAG07rtsQxBtcmUEoxO7cQJKgFgaBiGzJm3dte3XbTjbuV2G2wyUGmjB1YhY6w1U7numCQCFbjefowSoNAcQQiiNwwi8I2DJwJQncocL-pwNCoHo60POysKUPAnD3XgrqMsiXA8KNgI3KIfDWbdO7QAUcNgIcHydZI3A0+9Q3SBYbD4sjwgtag9HaGtTKQoqGB9q6cTQQmNClBtWnHKw5DxLgSjSIywRkwAJEKFkFBy8qIHouQrBtuwlEOs0KMbc3vNSGinKAicmWgeCZBnxCmyNtv6fRnbJDuJT7YdPOCPisDCLd+J8KqcDWWjwPBaDz26yPvA8IoGDQCCTJYKq8AuMyvB8zKGBSzuCAYN7xsRXOuLcyt2pX3VgVE8QA\" rel=\"nofollow\">Our Answer<\/a>.<\/p>\n<h2>The Challenge<\/h2>\n<h3>Beginner\/Learner Challenge<\/h3>\n<p><a href=\"https:\/\/gist.github.com\/gists\/927ccc66ae3022dc64c4f650109b937a\/927ccc66ae3022dc64c4f650109b937a-5\" rel=\"nofollow\">Help sort out a large array of pumpkins, and then get cooking soup.<\/a><\/p>\n<h3>Intermediate\/Advanced Challenge<\/h3>\n<p><a href=\"https:\/\/gist.github.com\/gists\/927ccc66ae3022dc64c4f650109b937a\" rel=\"nofollow\">Fresh back from robotics camp, can you make the perfect punch mixer bot?<\/a><\/p>\n<h2>How To Share Your Solution<\/h2>\n<p>Once you feel you have completed the challenge, you will need to select the <strong>Share<\/strong> button in the playground. This will automatically copy a playground URL to your clipboard.<\/p>\n<p>Then either:<\/p>\n<ul>\n<li>Go to Twitter, and create a tweet about the challenge, add the link to your code and mention the <a href=\"https:\/\/twitter.com\/typescript\" rel=\"nofollow\">@TypeScript<\/a> Twitter account with the hashtag <a href=\"https:\/\/twitter.com\/search?q=%23TypeOrTreat\" rel=\"nofollow\">#TypeOrTreat<\/a>.<\/li>\n<li>Leave us a comment with your feedback on the <a href=\"https:\/\/dev.to\/typescript\" rel=\"nofollow\">dev.to<\/a> post, or in this post.<\/li>\n<\/ul>\n<h3>Best Resources for Additional Help<\/h3>\n<p>If you need additional help you can utilize the following:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/intro.html\" rel=\"nofollow\">The New TypeScript Handbook<\/a><\/li>\n<li>The <a href=\"https:\/\/discord.com\/invite\/typescript\" rel=\"nofollow\">TypeScript Community Discord<\/a><\/li>\n<li>The comments on each <a href=\"https:\/\/dev.to\/typescript\" rel=\"nofollow\">Dev.to<\/a> post!<\/li>\n<li>Our previous <a href=\"https:\/\/www.typescriptlang.org\/play\/#gist\/303ebff59a6fc37f88c86e86dbdeb0e8-0\" rel=\"nofollow\"><code>Type | Treat<\/code> 2020 challenges<\/a><\/li>\n<\/ul>\n<p>Happy Typing \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Type | Treat Challenge 2 Welcome to the second Type | Treat 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&#8217;re on day two, which means going over the answers from yesterday and showcasing 2 new challenges. Yesterday&#8217;s Solution [&hellip;]<\/p>\n","protected":false},"author":6925,"featured_media":3143,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3156","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Type | Treat Challenge 2 Welcome to the second Type | Treat 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&#8217;re on day two, which means going over the answers from yesterday and showcasing 2 new challenges. Yesterday&#8217;s Solution [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/users\/6925"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/comments?post=3156"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3156\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media\/3143"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media?parent=3156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=3156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=3156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}