Type | Treat (Type or Treat) – Tag 2/5

Kommen wir nun zum zweiten Tag, der Type or Treat Challenge. Lass uns gemeinsam heute einen Blick auf meinen Lösungsansatz bzw. Lösungsvorschlag werfen. In dieser Challenge, bekommen wir eine Liste an Kürbissen. Aus diesen sollen wir drei Typen ableiten, um diese Kürbisse entsprechend kategorisieren zu können.

Damit wir dies korrekt ableiten können, hier einmal die List der Kürbisse.

const pumpkins = [
    { color: "green", soundWhenHit: "dull thud" },
    { color: "purple", soundWhenHit: "echo-y" },
    { color: "green", soundWhenHit: "dull thud" },
    { color: "white", soundWhenHit: "squishy" },
    { color: "orange", soundWhenHit: "echo-y" },
    { color: "green", soundWhenHit: "dull thud" },
    { color: "orange", soundWhenHit: "echo-y" },
    { color: "blue", soundWhenHit: "echo-y" },
    { color: "orange", soundWhenHit: "echo-y" }
]

Als nächstes wollen wir uns einmal die Typen ansehen, welche von uns definiert werden wollen.

type UnderripePumpkin = {}
type RipePumpkin = {}
type OverripePumpkin = {}

Mit Blick auf das Array, wird klar, dass wir die Eigenschaften ‚color‘ und ’soundWhenHit‘ in die Typen einbringen müssen. Als Ausbaustufe, kann sogar noch ein Union Type für die Farbe (color) der Kürbisse erzeugt werden. Darauf habe ich in meinem Lösungsvorschlag explizit verzichtet.

Demnach komme ich auf folgende Lösung:

type UnderripePumpkin = {
    color: string;
    soundWhenHit: "dull thud";
}
type RipePumpkin = {
    color: string;
    soundWhenHit: "echo-y";
}
type OverripePumpkin = {
    color: string;
    soundWhenHit: "squishy";
}

Im nächsten Fall möchten wir, dass eine Funktion den Typen eingrenzt, sprich wir wollen nach dem Funktionsaufruf ‚isRipe‘ explizit den Typen auf ‚RipePumpkin‘. Hierfür bietet uns, TypeScript sogenannte TypeGuards.

function isRipe(pumpkin: any): pumpkin is RipePumpkin { // TypeGuard: Pumpkin auf RipePumpkin
    return "soundWhenHit" in pumpkin && pumpkin.soundWhenHit === "echo-y"
}

const pumpkinsForPie = pumpkins.filter(isRipe)
//    ^?
const soup = cookPumpkinSoup(pumpkinsForPie)

Mehr zum Thema ‚Type Guard‘ kannst du in diesem Blog Beitrag nachlesen: https://r3d-soft.de/?p=1

Intermediate Challenge

In der Intermediate Challenge, müssen wir die Klasse ‚PunchMixer‘ vervollständigen. Hierbei ist es wichtig zu verstehen, dass es sich dabei um eine Klassenvariable handelt, welche zwei verschiedene Typen hat (getter und setter unterscheiden sich hier).

Dieses Konstrukt wurde mit TypeScript 4.3 eingeführt, wenn du mehr dazu wissen willst hier der entsprechende Beitrag dazu: https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#separate-write-types

Demnach sieht meine Lösung wie folgt aus:

 class PunchMixer<T> {
  #punch: Punch = {flavour: '', ingredients: []};

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

  public set punch(input: Punch | Punch['ingredients'][number]) {
      switch (typeof input) {
        case "string":
          this.#punch.ingredients.push(input);
          break;
        case "object":
          if ('flavour' in input) {
            this.#punch = input;
          } else {
            this.#punch.ingredients.push(input);
          }
          break;
      }
  }

  public vend(): T; // Implementierung ist hier unerheblich
}
1880cookie-checkType | Treat (Type or Treat) – Tag 2/5

Kommentar verfassen