{"id":3179,"date":"2021-10-30T07:00:11","date_gmt":"2021-10-30T15:00:11","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=3179"},"modified":"2021-10-30T07:07:24","modified_gmt":"2021-10-30T15:07:24","slug":"type-treat-wrap-up","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/type-treat-wrap-up\/","title":{"rendered":"Type | Treat \u2013 Wrap-up"},"content":{"rendered":"<h2>Type | Treat Challenge Wrap-up<\/h2>\n<p>That&#8217;s all the challenges done! If you missed any of the challenges they&#8217;re all available in <a href=\"https:\/\/www.typescriptlang.org\/play?#gist\/927ccc66ae3022dc64c4f650109b937a\" rel=\"nofollow\">the Playground here<\/a>. Let&#8217;s talk through the final answers to day 5&#8217;s challenges.<\/p>\n<h2>Yesterday&#8217;s Solution<\/h2>\n<h3>Beginner\/Learner Challenge<\/h3>\n<p>In this challenge we were working with an existing object literal which had been <code>as const<\/code>&#8216;d. The goal was to use <code>keyof<\/code> and <code>typeof<\/code> to extract interesting sets of strings from the object. The first being the keys in the object:<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span class=\"pl-md\"><span class=\"pl-md\">-<\/span> type SchemeNames = \"background\" | \"textColor\" | \"highlightOne\"<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> type SchemaNames = keyof typeof scheme<\/span><\/pre>\n<\/div>\n<p>Ideally, you might have noticed the &#8216;key of&#8217; in the comment, which could have led you to <code>keyof<\/code>, from there you needed to re-use <code>typeof<\/code> to extract the type from <code>scheme<\/code>. This gets all of the keys from that constant.<\/p>\n<p>Next, we asked if you could improve<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-k\">function<\/span> <span class=\"pl-en\">possibleSchemeItems<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">colors<\/span>: <span class=\"pl-smi\">any<\/span><span class=\"pl-kos\">)<\/span>: <span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-k\">const<\/span> <span class=\"pl-s1\">keys<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-smi\">Object<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">keys<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">colors<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-k\">as<\/span> <span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span>\r\n    <span class=\"pl-k\">return<\/span> <span class=\"pl-s1\">keys<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>In this case, you can switch <code>string<\/code> to <code>SchemeNames<\/code> &#8211; this example was made so that there was an interesting function to play around with. You could switch <code>colors<\/code> to <code>typeof schema<\/code> but nothing you do around <code>Object.keys<\/code> would keep the types retained. This is kind of interesting, the reasoning is that TypeScript cannot make <em>reasonable<\/em> guarantees that the return value of <code>Object.keys<\/code> actually <em>is<\/em> <code>keyof typeof colors<\/code> (because of JavaScript prototype chaining) and so you have to re-type that line. Interesting.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-k\">function<\/span> <span class=\"pl-en\">possibleSchemeItems<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">colors<\/span>: <span class=\"pl-k\">typeof<\/span> <span class=\"pl-s1\">scheme<\/span><span class=\"pl-kos\">)<\/span>: <span class=\"pl-smi\">SchemaNames<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-k\">const<\/span> <span class=\"pl-s1\">keys<\/span> <span class=\"pl-c1\">=<\/span> <span class=\"pl-smi\">Object<\/span><span class=\"pl-kos\">.<\/span><span class=\"pl-en\">keys<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">colors<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-k\">as<\/span> <span class=\"pl-smi\">SchemaNames<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-kos\">]<\/span>\r\n    <span class=\"pl-k\">return<\/span> <span class=\"pl-s1\">keys<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>Next we had you figure out how to get the values of <code>schema<\/code> as a union:<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span class=\"pl-md\"><span class=\"pl-md\">-<\/span> type PossibleColors = '#242424' | '#ffa52d' | '#cafe37'<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> type PossibleColors = typeof scheme[SchemaNames]<\/span><\/pre>\n<\/div>\n<p>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.<\/p>\n<p>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 <code>Record<\/code> to see if you knew that the first parameter can be a list of keys:<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span class=\"pl-md\"><span class=\"pl-md\">-<\/span> type Scheme = Record&lt;string, string&gt;;<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> type Scheme = Record&lt;SchemaNames, string&gt;;<\/span><\/pre>\n<\/div>\n<p>Which would cause a compiler error with <code>previousScheme<\/code> &#8211; letting you know it worked.<\/p>\n<p><a href=\"https:\/\/www.typescriptlang.org\/play?#code\/PTAEDEHsCdQFwBYFNQAkCGAbTkDuSkA7UfJAayIBMAaUAT0gFcByANxUqQGMBLTy+JFBcE6QgHMUiJACgQoAM5I4oSADNhkHNAWg1Mek1gNGsfACMFPOFKHmUCgA6RIZOvGQBbJJRlywAOoIPJgoJszQKMiRtCagnuju6Lr42KDoXCqYPBTpoOIuAgpcTHD+6YQCPJ6O0JDsHiglnObJKLjBoYYskaDRSABcfiWECirFXigAvKAA3jKgi6CtXGTidYyVA6DMAMQATAAsR0fM1AtLNgAecADCWjDbe2pq6ACs+5RnF4vB4gjZf5wADyhEGO12XHQaiQAGYAOzfJZ9Hj-QEIOAAFVwkCeuwAnEh9gAGF7MGQAX3SuhGYz88gAklkXGRdNlciZYHA6I52sERKBIrUkEpCHBdFhMKBnAorOYuuUStpdDxdKVVBpKOgbLQocQ4iIxJIPKr4DzbKByvZhJFtT5QJQeJFMph3Go6p5GqAKHQ1RoAAYTJDef3pcz1JAAfj83N5oAAyiJg+gAHLoby6GY+9Rm3k5oPeelgJmgHCuNk5KT9Zi6RCmxhKNSMKVNwiZHiQYj+mVy0KJyZM4MKf3lDo8AU45sCSJwUzEaSgQjpkUar1Koy6cyMFTWQXKOcS8pjaA8CQS6DQRIAOlAtzE3VA1VqEZNCmjMlb7c70sgsp48qQftgyQQdPAUAAKdcdG2MQ6AASm2ICEjTDMAG0AF05h+TRRhUH1M1AYFzAAK24OAr3wyCHh0ODqQTJNkOXBQMOwmc529JBfUpItQAATSYRRnDgGwBDESBpFgKElFXe9Si1ETFDgE8JFATYO0IXUxHKA1QnvOtdEYRxBGWdwyzIU9xHSFQF1jFB8wY9AKl8eRpGIU9OCuCzVGs5Afz-ADFAcxcmPfFzzVAAAFX9eyQe5lVAGY9hOY5DmYUAAB8IRed5PjSzK9ihGEEXJWzIui-9QjimACNs+zJlQ7MNFqjQCyQdC-HKFM8A8bVujYJpdLBARDMaaTbIUWIBNwMRrKEBIKCPUwq16iSkBrPISkcdwcwXGBUVPLBAsmRSQildANkqK9yjvfUBPmhwlp6nyUG7SJWA7BskKQUN7BwXATrSUQFHKBcFGXDjfTohdAwY77VKM9Bw3Yd9Sq+hLQAAJW4GBKAAHiQ1MmNoY8LIAPgAbmGTsxmlN6PoUL7ENh9H5mRFY1guyg8QARl5vmkUuJAbiq6A8S4AA2YkAA5iWJAXflRAFFZBME8Vl8XWm574KXJoA\" rel=\"nofollow\">Our answer<\/a><\/p>\n<h3>Intermediate\/Advanced Challenge<\/h3>\n<p>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.<\/p>\n<p>The total change we were looking for was this:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-k\">function<\/span> <span class=\"pl-en\">handleSale<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">events<\/span>: <span class=\"pl-smi\">Record<\/span><span class=\"pl-kos\">&lt;<\/span><span class=\"pl-smi\">string<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">e<\/span>: <span class=\"pl-smi\">Books<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-smi\"><span class=\"pl-k\">void<\/span><\/span><span class=\"pl-kos\">&gt;<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span class=\"pl-c\">\/\/ ... <\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>To:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-k\">function<\/span> <span class=\"pl-en\">handleSale<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">events<\/span>: <span class=\"pl-kos\">{<\/span> <span class=\"pl-kos\">[<\/span><span class=\"pl-smi\">Book<\/span> <span class=\"pl-k\">in<\/span> <span class=\"pl-smi\">Books<\/span> <span class=\"pl-k\">as<\/span> <span class=\"pl-s\">`on<span class=\"pl-s1\"><span class=\"pl-kos\">${<\/span><span class=\"pl-smi\">Book<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-s\">\"genre\"<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">}<\/span><\/span>`<\/span><span class=\"pl-kos\">]<\/span>?: <span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">e<\/span>: <span class=\"pl-smi\">Book<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-smi\"><span class=\"pl-k\">void<\/span><\/span> <span class=\"pl-kos\">}<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-kos\">{<\/span>\r\n  <span class=\"pl-c\">\/\/ ... <\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>Getting there is a bit of a jump!<\/p>\n<p>We first asked you to switch the <code>string<\/code> in the <code>Record<\/code> to be <code>Books<\/code>:<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span class=\"pl-md\"><span class=\"pl-md\">-<\/span> function handleSale(events: Record&lt;string, (e: Books) =&gt; void&gt;) {<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> function handleSale(events: Record&lt;keyof IncomingBookMap, (e: Books) =&gt; void&gt;) {<\/span><\/pre>\n<\/div>\n<p>The next step was to remove the <code>Record<\/code> and replace it with its underlaying mapped type:<\/p>\n<div class=\"highlight highlight-source-diff\">\n<pre><span class=\"pl-md\"><span class=\"pl-md\">-<\/span> function handleSale(events: Record&lt;string, (e: Books) =&gt; void&gt;) {<\/span>\r\n<span class=\"pl-mi1\"><span class=\"pl-mi1\">+<\/span> function handleSale(events: { [Book in keyof IncomingBookMap]?: (e: Books) =&gt; void }) {<\/span><\/pre>\n<\/div>\n<p>The <code>?<\/code> being the key that if you searched the TypeScript documentation for <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/mapped-types.html#mapping-modifiers\" rel=\"nofollow\">&#8220;mapping modifier&#8221;<\/a> you&#8217;d see the documentation around <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/mapped-types.html#mapping-modifiers\" rel=\"nofollow\">mapped types<\/a> which we also improved in the process of making this challenge.<\/p>\n<p>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 <code>as<\/code> in the mapped type.<\/p>\n<pre><code>- function handleSale(events: { [Book in keyof IncomingBookMap]?: (e: Books) =&gt; void }) {\r\n+ function handleSale(events: { [Book in Books as `on${Book[\"genre\"]}`]?: (e: Book) =&gt; void }) {\r\n<\/code><\/pre>\n<p>The <code>IncomingBookMap<\/code> existed specifically to add the prefix <code>on<\/code> 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.<\/p>\n<p>This system is <em>more or less<\/em> how the DOM&#8217;s event system works, and is what the idea is loosely based on, <a href=\"https:\/\/github.com\/microsoft\/TypeScript-DOM-lib-generator\/blob\/008041c9638d034fc2cb366994c9bd79a43fac36\/baselines\/dom.generated.d.ts#L4549-L4563\">from <code>lib.dom.d.ts<\/code><\/a>:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-k\">interface<\/span> <span class=\"pl-smi\">DocumentAndElementEventHandlersEventMap<\/span> <span class=\"pl-kos\">{<\/span>\r\n    <span class=\"pl-s\">\"copy\"<\/span>: <span class=\"pl-smi\">ClipboardEvent<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-s\">\"cut\"<\/span>: <span class=\"pl-smi\">ClipboardEvent<\/span><span class=\"pl-kos\">;<\/span>\r\n    <span class=\"pl-s\">\"paste\"<\/span>: <span class=\"pl-smi\">ClipboardEvent<\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span>\r\n\r\n<span class=\"pl-k\">interface<\/span> <span class=\"pl-smi\">DocumentAndElementEventHandlers<\/span> <span class=\"pl-kos\">{<\/span>\r\n        <span class=\"pl-c1\">addEventListener<\/span><span class=\"pl-c1\">&lt;<\/span><span class=\"pl-smi\">K<\/span> <span class=\"pl-k\">extends<\/span> <span class=\"pl-k\">keyof<\/span> <span class=\"pl-smi\">DocumentAndElementEventHandlersEventMap<\/span><span class=\"pl-c1\">&gt;<\/span><span class=\"pl-kos\">(<\/span><span class=\"pl-s1\">type<\/span>: <span class=\"pl-smi\">K<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">listener<\/span>: <span class=\"pl-kos\">(<\/span><span class=\"pl-smi\">this<\/span>: <span class=\"pl-smi\">DocumentAndElementEventHandlers<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">ev<\/span>: <span class=\"pl-smi\">DocumentAndElementEventHandlersEventMap<\/span><span class=\"pl-kos\">[<\/span><span class=\"pl-smi\">K<\/span><span class=\"pl-kos\">]<\/span><span class=\"pl-kos\">)<\/span> <span class=\"pl-c1\">=&gt;<\/span> <span class=\"pl-smi\">any<\/span><span class=\"pl-kos\">,<\/span> <span class=\"pl-s1\">options<\/span>?: <span class=\"pl-smi\">boolean<\/span> <span class=\"pl-c1\">|<\/span> <span class=\"pl-smi\">AddEventListenerOptions<\/span><span class=\"pl-kos\">)<\/span>: <span class=\"pl-smi\"><span class=\"pl-k\">void<\/span><\/span><span class=\"pl-kos\">;<\/span>\r\n<span class=\"pl-kos\">}<\/span><\/pre>\n<\/div>\n<p>Roughly translates to english as &#8220;DocumentAndElementEventHandlersEventMap&#8221; shows how to handle <code>document.addEventListener(\"copy\", (evt) =&gt; { ... })<\/code> and what to map the first argument of that function to. The DOM types can&#8217;t really switch to use a template literal because not all properties have an <code>on<\/code> prefix, but it&#8217;s a pretty logical expansion of the idea in specific cases.<\/p>\n<p><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\" rel=\"nofollow\">Our answer<\/a>.<\/p>\n<h3>Thanks!<\/h3>\n<p>There are a few people involved in getting <code>Types | Treat<\/code> running whose name you don&#8217;t see on the masthead: <a href=\"https:\/\/twitter.com\/NoWaySheCodes\" rel=\"nofollow\">Gabriella<\/a> and <a href=\"https:\/\/twitter.com\/drosenwasser\" rel=\"nofollow\">Daniel<\/a> on the TypeScript team, and the folks in the TypeScript Community Discord &#8211; especially <a href=\"https:\/\/github.com\/webstrand\">webstrand<\/a> and <a href=\"https:\/\/twitter.com\/M_Rutter\" rel=\"nofollow\">michael<\/a>. My wife, <a href=\"https:\/\/github.com\/dangermcshane\">Danger<\/a>, should probably also get a shout for helping to provide themes &#8211; we&#8217;ve done 40 challenges so far and have to dig pretty deep occasionally to be fun and topical.<\/p>\n<h4>Feedback<\/h4>\n<p>If you gave <code>Types | Treat<\/code> a shot, we love for you to run through our <a href=\"https:\/\/www.surveymonkey.com\/r\/FSQ7DLC\" rel=\"nofollow\">6 question survey<\/a> which help us figure out how to change and improve. Feedback on Twitter is useful, but there&#8217;s only so much context you can gve in 280 characters!<\/p>\n<h3>From here?<\/h3>\n<p>If you&#8217;ve not done <a href=\"https:\/\/www.typescriptlang.org\/play\/#gist\/303ebff59a6fc37f88c86e86dbdeb0e8-0\" rel=\"nofollow\">the 2020 <code>Type | Treat<\/code><\/a>, it&#8217;s also good!<\/p>\n<p>There&#8217;s a small write-up with some of the behind the scenes details for Type | Treat on the <a href='https:\/\/github.com\/microsoft\/TypeScript-Website\/issues\/130#issuecomment-955249853'>TypeScript Website updates thread<\/a>.<\/p>\n<p>If you want to challenge yourself further, check out <a href=\"https:\/\/github.com\/type-challenges\/type-challenges#intro\">types-challenges<\/a> this clever system of type challenges goes all the way up to &#8220;very challenging for the TypeScript team&#8221; and also run entirely in the TypeScript Playgound. It&#8217;s great work and a fun system for learning.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Type | Treat Challenge Wrap-up That&#8217;s all the challenges done! If you missed any of the challenges they&#8217;re all available in the Playground here. Let&#8217;s talk through the final answers to day 5&#8217;s challenges. Yesterday&#8217;s Solution Beginner\/Learner Challenge In this challenge we were working with an existing object literal which had been as const&#8216;d. The [&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-3179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Type | Treat Challenge Wrap-up That&#8217;s all the challenges done! If you missed any of the challenges they&#8217;re all available in the Playground here. Let&#8217;s talk through the final answers to day 5&#8217;s challenges. Yesterday&#8217;s Solution Beginner\/Learner Challenge In this challenge we were working with an existing object literal which had been as const&#8216;d. The [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3179","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=3179"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/3179\/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=3179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=3179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=3179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}