Type | Treat 2021 - Day 3
Tags: typescript, challenge
Published: 2021-10-27 20:25:16

---
title: Type | Treat 2021 - Day 3
published: true
description: The TypeScript Team challenges
tags: typescript,challenge
series: type | treat 2021
cover_image: https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2021/10/type-or-treat-2021.png
---
# Type | Treat Challenge 3

Welcome to the third `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're on day three, which means going over the answers from [yesterday](https://devblogs.microsoft.com/typescript/type-treat-2021-day-2/) and have 2 new challenges.

## Yesterday's Solution

### Beginner/Learner Challenge

There is many ways to decide how to type existing data, you could use [literal types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) when you're sure of the exact formats - or be more liberal and use `string` when you expect a variety. We opted for literals, but using `string` is totally cool too.

```ts 
type UnderripePumpkin = {
    color: "green",
    soundWhenHit: "dull thud"
}
type RipePumpkin = {
    color: "purple" | "orange" | "blue",
    soundWhenHit: "echo-y"
}
type OverripePumpkin = {
    color: "green" | "white",
    soundWhenHit: "squishy"
}
```

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

```diff
- function isRipe(pumpkin: any) {
+ function isRipe(pumpkin: any): pumpkin is RipePumpkin {
       return "soundWhenHit" in pumpkin && pumpkin.soundWhenHit === "echo-y"
  }
```

Successfully completing this challenge would have no errors, and the type for.

[Our answer](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).

### Intermediate/Advanced Challenge 

This challenge was first about understanding different read vs write properties available in both `classes` and `interface`/`typed` objects. Personally, I've seen this with `document.location` 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 `punch` which for me is generally a 'throw it all in and see what happens' style of drink. 

```ts
class PunchMixer {
  #punch: Punch = {flavour: '', ingredients: []};

  public get punch(): Punch {
      return this.#punch;
  }

  public set punch(punch: Punch | Punch['ingredients'][number]) {
      if (typeof punch === 'string') {
          this.#punch.ingredients.push(punch);
      } else if ('flavour' in punch) {
          this.#punch = punch;
      } else {
          this.#punch.ingredients.push(punch);
      }
  }
}
```

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. 

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 `vend` function was.

```diff
- class PunchMixer {
+ class PunchMixer<MixerType> {
+    mixer!: MixerType;

  // ...
+   public vend(): MixerType {
+        return this.mixer;
+    }
  }
```

We were not too worried about how you passed back the `MixerType` - our first draft had `return {} as MixerType` but a private field feels nicer. 


[Our Answer](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).

## The Challenge

### Beginner/Learner Challenge

[Figure out how to stop people giving you bad strings for your custom lengths.](https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-9)


### Intermediate/Advanced Challenge  

[Stop losing your literals in Halloween posters](https://www.typescriptlang.org/play?#gist/927ccc66ae3022dc64c4f650109b937a-10)

## How To Share Your Solution

Once you feel you have completed the challenge, you will need to select the **Share** button in the playground. This will automatically copy a playground URL to your clipboard.

Then either:

 - Go to Twitter, and create a tweet about the challenge, add the link to your code and mention the [@TypeScript](https://twitter.com/typescript) Twitter account with the hashtag [#TypeOrTreat](https://twitter.com/search?q=%23TypeOrTreat).

 - Leave us a comment with your feedback on the [dev.to](https://dev.to/typescript) post, or in this post.

### Best Resources for Additional Help

If you need additional help you can utilize the following:

- [The New TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
- The [TypeScript Community Discord](https://discord.com/invite/typescript)
- The comments on each [Dev.to](https://dev.to/typescript) post!
- Our previous [`Type | Treat` 2020 challenges](https://www.typescriptlang.org/play/#gist/303ebff59a6fc37f88c86e86dbdeb0e8-0)


Happy Typing :)