Zum Inhalt springen

Aufgabe 03 - TypeScript-Katas

Zu Zen-Modus wechseln

Bevor Asynchronität und Framework dazukommen, muss das Typisieren in die Finger: kurze, unabhängige Übungsstücke (Katas) rund um Funktionen, Interfaces und Union Types (siehe Kapitel JavaScript und TypeScript). Ziel ist Routine: zügig typisieren, Compiler-Meldungen lesen, Fachliches als Typen ausdrücken.

  • Kapitel JavaScript und TypeScript, inklusive des Abschnitts zu any und unknown; Ihr Setup aus Aufgabe 01.
  • Sie typisieren Funktionen und Datenstrukturen vollständig und zügig.
  • Sie übersetzen Compiler-Fehlermeldungen in verständliche Aussagen.
  • Sie modellieren Fachbegriffe einer Aufgabenstellung als Typen.
  • Reproduktion: eingeübte Typmuster auf kleine Aufgaben anwenden (Teil A).
  • Reorganisation und Transfer: Fehlermeldungen interpretieren, Fallunterscheidungen aus Typen ableiten (Teile B und C).
  • Reflexion, Problemlösung und Urteilsbildung: eine Domäne so modellieren, dass der Compiler fachliche Regeln erzwingt (Teil D).

Die Übung ist auf etwa zwei Stunden ausgelegt. Alle Katas landen in katas.ts mit je zwei Testaufrufen; Teil D ist der Expertenteil.

  1. median(values: number[]): der Median der Liste (sortierte Kopie, nicht das Original sortieren!).
  2. initials(firstName, lastName): aus “Alex Muster” wird “A.M.”.
  3. celsiusToFahrenheit(celsius) samt Umkehrfunktion; Rundreise mit console.assert prüfen.
  1. interface Appointment (Titel, Beginn als Date, Dauer in Minuten, optionaler Raum) und endOf(appointment): liefert den Endzeitpunkt als Date.
  2. describeRoom(appointment): liefert den Raum oder "kein Raum reserviert"; Pflicht: ??, kein if.
  3. overlaps(a, b): überschneiden sich zwei Termine? Testen Sie bewusst die Grenzfälle (Ende = Beginn).
  1. describeInput(input: string | number): bei Strings die Länge, bei Zahlen das Vorzeichen. Der Compiler erzwingt die Fallunterscheidung mit typeof; probieren Sie aus, was ohne sie passiert, und notieren Sie die Meldung.
  2. type Grade = 1 | 2 | 3 | 4 | 5 und isPassing(grade: Grade): Was meldet der Compiler bei isPassing(6)? Original notieren und in eigene Worte übersetzen.
  3. parseAppointment(raw: unknown): Appointment | null: Der Wert kommt aus JSON.parse und ist damit von unbekannter Form. Prüfen Sie ihn, bevor Sie ihn verwenden, und liefern Sie null, wenn die Form nicht stimmt. Notieren Sie zusätzlich die Compiler-Meldung, die beim direkten Zugriff auf raw.title erscheint.
  4. Sie erhalten fünf Codezeilen mit Typfehlern (werden ausgeteilt; darunter Zahl an String-Parameter, Zugriff auf möglicherweise undefined, falscher Rückgabetyp). Für jede: Meldung im Original, Übersetzung in einen verständlichen Satz, Behebung. Die Übersetzung ist der wichtigste Teil; Compiler-Englisch muss man lesen lernen.

Teil D - Expertenteil: Das Safi-Sortiment im Typsystem

Abschnitt betitelt „Teil D - Expertenteil: Das Safi-Sortiment im Typsystem“

Modellieren Sie das Sortiment der Schulkantine “Safi” - Brötchen, Nudeln, Salat, Getränke, Joghurt und dergleichen - so, dass der Compiler die fachlichen Regeln erzwingt:

  1. Artikel haben Name und Preis; ihre Ernährungsart ist "vegetarian" | "vegan" | "meat" (etwa Käsebrötchen vegetarisch, Schinkenbrötchen mit Fleisch, Apfelsaft vegan). Manchmal macht Safi einen “Aktionsartikel des Tages” und diese haben dann zusätzlich einen Wochentag ("monday" | ... | "friday").
  2. Schreiben Sie vegetarianOnly(items) so, dass der Rückgabetyp Artikel mit Fleisch unmöglich macht. Hinweis: Definieren Sie die Ernährungsart als eigenen Union Type und einen verengten Typ für das Ergebnis; die Schreibweise für eigene Prüffunktionen (item is VegetarianItem) steht im Kapitel im Abschnitt zu any und unknown.
  3. Beweisen Sie die Erzwingung: Ein Testaufruf, der dem Ergebnis ein Schinkenbrötchen unterschieben will, muss ein Compile-Fehler sein (als Kommentar mit der Meldung dokumentieren).
  4. Beurteilen Sie in drei Sätzen: Welche fachliche Regel steckt jetzt im Typsystem statt in einer Laufzeitprüfung, und was ist der Gewinn?
  1. Warum sortiert median eine Kopie statt des übergebenen Arrays?
  2. Wie erzwingt string | number eine Fallunterscheidung, und womit trifft man sie?
  3. Was ist der Unterschied zwischen type Grade = 1 | 2 | 3 | 4 | 5 und number mit Laufzeitprüfung?
  4. Wozu ein optionales Feld (room?) statt room: string | null? Nennen Sie einen Unterschied.
  5. Was bedeutet die Rückgabetyp-Schreibweise item is VegetarianItem?
  6. Warum verlangt ein Wert vom Typ unknown eine Prüfung, bevor man ein Feld liest?

katas.ts (kompiliert ohne Fehler, alle Testaufrufe korrekt) mit den übersetzten Fehlermeldungen als Kommentar.